在Python中,如果参数错误则返回“None”而不是创建新实例
当你创建一个类的实例时,如果传入了错误的参数,怎么才能不创建新的实例,而是直接返回一个“None”呢?
这是我的应用场景:有时候这是允许的。我想用一串整数来构建树。我希望在这个列表中用None来表示树的叶子,所以我只想返回一个None,而不是返回一个空的树节点。
6 个回答
0
在init方法里,如果遇到错误,就直接返回。这就可以解决问题。
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
如果你想创建另一个类或者进行一些更复杂的操作,你需要在你的类里写一个__new__构造函数,而不是在__init__构造函数里做这些事情。
1
如果有参数,就创建一个类的实例;如果没有参数,就返回一个空对象。
class Test:
def __init__(self, *args, **kwargs):
pass
def __new__(cls, *args, **kwargs):
if kwargs or args:
return super().__new__(cls)
1
如果你想把一个对象设置为 None
,我猜在你代码的其他地方,你会检查这个对象是否是 None
(在你认为它是一个真正的节点之前)。所以,也许可以用一个自定义的 __nonzero__
方法来解决这个问题(可以参考 这个问题),比如:
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...
7
大部分的回答都不太对。正确的做法是在类的 __new__
方法里检查你的参数,如果检查不通过就返回 None
,如果通过了就返回 ins
。
这就是你需要的内容:
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
显然,你可以用自己的实现来替换 _validate
方法。
4
可以查看这个回答,它是关于Python中的__init__
返回创建失败的问题。
简单来说,你可以使用__new__
来实现你想要的功能,但实际上,按照Python的风格,最好的做法是抛出一个异常。可以说,Python的风格是让__init__
方法更简单,仅仅用于初始化,而不是可能会失败的操作。