Reputation: 103
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.
Upvotes: 6
Views: 6670
Reputation: 894
If the parameters are present create class instance else None Object
class Test:
def __init__(self, *args, **kwargs):
pass
def __new__(cls, *args, **kwargs):
if kwargs or args:
return super().__new__(cls)
Upvotes: 1
Reputation: 2133
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.
Upvotes: 7
Reputation: 4260
In the init, in case of exception just put a return. That will do the trick.
class MyTest(object):
def __init__(self, * args, **kwargs):
try:
# Your code goes here
except:
print "No donuts buddy"
return
# An empty return will return a None
In case you wish to instantiate another class or any such advanced maneuvers, you need to write a __ new __ constructor in your class instead of doing it in the __ init __ constructor.
Upvotes: 0
Reputation: 138
If you want to set the object to None
, I assume that in other places of your code, you are going to test for the object being None
(before assuming it's a genuine Node). So maybe, a custom __nonzero__
method could do the trick (see this question), eg:
class MyNode():
def __init__(self, ...):
self.ok = False
if ...genuine node...:
self.ok = True
...
def __nonzero__(self):
return self.ok
node = MyNode(...)
if node:
...node code...
else:
...leaf code...
Upvotes: 1
Reputation: 610
you can use the isinstance(object, class) function inside an if statment to check each parameter for example:
if not isinstance(num, int):
return None
Upvotes: -4
Reputation: 3947
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.
Upvotes: 4