在Python中,如果参数错误则返回“None”而不是创建新实例

6 投票
6 回答
6215 浏览
提问于 2025-04-18 17:36

当你创建一个类的实例时,如果传入了错误的参数,怎么才能不创建新的实例,而是直接返回一个“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__方法更简单,仅仅用于初始化,而不是可能会失败的操作。

撰写回答