使用 __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 等方面很好,所以可以使用适合你的东西
重复使用 __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 等方面很好,所以可以使用适合你的东西