when creating instance of a class, if wrong parameters are given. how do I NOT to create a new instance and return the reference, but instead just return a "None"
here is my application: Because it is allowed sometime. My application is to build trees from a list of integers. I want to use None in the list to represent a leaf. so I just want to return a None instead of a empty tree node.
Most of these answers aren't right. The appropriate way to do this is to validate your arguments in the class's __new__ method, and return None if validation fails or ins if validation succeeds.
Here's what you're looking for:
import pytest # for testing
class ValidatedModel:
    def __init__(self, *, name=None):
        self.name = name
    @classmethod
    def _validate(cls, *args, **kwargs):
        try:
            assert not args
            assert list(kwargs.keys()) == ['name']
            assert len(kwargs['name']) > 5 and len(kwargs['name']) < 10
        except AssertionError:
            return False
        return True
    def __new__(cls, *args, **kwargs):
        if cls._validate(*args, **kwargs):
            return super().__new__(cls)
class TestValidatedModel:
    def test_success(self):
        vm = ValidatedModel(name='william')
        assert isinstance(vm, ValidatedModel)
    def test_kwarg_fail_unexpected_kwarg(self):
        vm = ValidatedModel(name='william', gender='M')
        assert vm is None
    def test_kwarg_fail_name_length_short(self):
        vm = ValidatedModel(name='bill')
        assert vm is None
    def test_kwarg_fail_name_length_long(self):
        vm = ValidatedModel(name='william johnson')
        assert vm is None
    def test_no_name_kwarg(self):
        vm = ValidatedModel()
        assert vm is None
Obviously you can replace the _validate method with your own implementation.
See this answer to Python __init__ return failure to create.
Basically, you can use __new__ to accomplish what you want, but really, the Pythonic way of doing this would be to throw an exception. Arguably, the Pythonic way would be to have a simpler __init__ method that is simply an initialization and not something that can fail at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With