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