使用 __init__ 方法更新对象的实例

Updating an instance of an object with the __init__ method

重复使用 __init__ 方法来更改属性值

Python 3.10 on Windows 64 位

假设我有一个 class,它有一个调用 __init__ 方法的 update 方法。 创建 update 方法是为了避免对属性进行多行赋值。

class Person:
     def __init__(self, name: str, age: int):
         self.name = name
         self.age = age

     def update(self, **attributes):
         self.__init__(**attributes)

对象实例化:

p = Person(name="Alex", age=32)
print(p.name, p.age)

>> Alex 32

之前的对象引用:

print(p)

>> <__main__.Person object at 0x0000028B4ED949A0>

调用更新方法:

p.update(name="Sam", age=80)
print(p.name, p.age)

>> Sam 80

之后的对象引用:

print(p)

>> <__main__.Person object at 0x0000028B4ED949A0>

很明显,引用没有变!

这样安全吗?内存中的对象引用是否有可能被更改?

显然,它的实际用途是用于具有多个参数并作为内部反应一次频繁修改的大型对象。有些参数是可选的,不会被修改。

如果我不这样做,我将不得不编写一连串我不想写的 if-else 语句。 :)

__init____new__ 不同,根本不处理内存引用。 self 已经是 __new__ 生成的有效对象,__init__ 对其进行了初始化。

为了清楚起见,您可以反过来做:

class Person:
     def __init__(self, name: str, age: int):
         # Signal to whoever will read your code
         # that the class is supposed to have these attributes
         self.name = None
         self.age = None
         self.update(name=name, age=age)

     def update(self, name: str, age: int):
         self.name = name
         self.age = age

现在 __init__ 不会被其他方法调用,所以不会出现混淆。

如果需要,除了 ForceBru 的回答

class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

    def update(self, **attributes):
        for attribute, value in attributes.items():
            if hasattr(self,attribute):
                setattr(self, attribute, value)
            else:
                raise AttributeError(f'{self.__name__} has no attribute: {attribute}')
        
x = Person(name='Henry',age=12)
print(f'name={x.name}, age={x.age}')
x.update(name='Joe')
print(f'name={x.name}, age={x.age}')
x.update(name='Kyle',age=20)
print(f'name={x.name}, age={x.age}')

给出输出

name=Henry, age=12
name=Joe, age=12
name=Kyle, age=20

这只是模板(您可能需要其他特定行为,例如不希望用户覆盖以 _ 开头的属性等)。

最终我会说 ForceBru 在 linters、intellisense 等方面很好,所以可以使用适合你的东西