如何在构造函数参数无效时返回None

29 投票
3 回答
28808 浏览
提问于 2025-04-18 16:31

目前我有这样的代码:

if name and password:
     user = User(name, password)
     ...do stuff

我想把它改成这样:

user = User(name, password)
if user:
     ...do stuff

我创建了一个 User() 类:

class User():
    def __init__(self, name, password):
        if name and password:
            self.name, self.password = name, password

但是在这种情况下,即使 namepasswordNoneuser 仍然会被创建(虽然是空的,但它依然存在,所以 if user: 的判断会返回真)。

我该如何在特定参数的情况下 创建一个对象呢?

3 个回答

1

像这样:

class User():
    def __init__(self, name, password):
        self._name = self._password = None
        self.name = name
        self.password = password

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name: str) -> None:
        if not name:
            raise TypeError("name is required")
        if len(name) < 5: # exemple
            raise ValueError("name must have 5 characters or more")
        self._name = name

    # Do the same for password

然后在你的代码中做类似的事情,或者把它放在一个类的方法里,作为工厂模式来返回它。

try:
    user = User(name, password)
except (TypeError, ValueError):
    user = None
1

这样做是不对的。你应该在你的用户类里添加一个叫做 check() 的方法。或者(更好的方法),创建一个 静态 方法 createUser(name, password)。它看起来像这样:

user = User.createUser(name, password)  
48

你需要使用一个叫做 __new__ 的方法;在 __init__ 被调用的时候,一个新的实例已经创建好了

class User(object):
     def __new__(cls, name, password):
         if name and password:
             instance = super(User, cls).__new__(cls)
             instance.name, instance.password = name, password
             return instance

不过,这样做有点不符合常规;当你调用一个类的时候,我会期待总是得到一个新的实例。你可以选择抛出一个异常,或者使用类方法来解决。

抛出异常的方式:

class User(object):
    def __init__(self, name, password):
        if not (name and password):
            raise ValueError('Empty name or password not allowed')
        self.name, self.password = name, password

try:
    user = User(name, password)
except ValueError:
    # oops, no username or password
else:
    # ...do stuff

或者使用一个类方法

class User(object):
    def __init__(self, name, password):
        self.name, self.password = name, password

    @classmethod
    def create_valid_user(cls, name, password):
        """Create a user, or return None if conditions are not met"""
        if not (name and password):
            return None
        return cls(name, password)

user = User.create_valid_user(name, password)
if user is not None:
    # ...do stuff

撰写回答