通过阅读文档,我完全了解getattr()和setattr()的作用。但它也明确表示getattr(x, 'foobar')
等价于x.foobar
和setattr(x, 'foobar', 123)
等价于x.foobar = 123
。
那么我为什么要使用它们呢?
因为您也可以使用动态变量:
somevar = 'foo'
getattr(x, somevar)
您不能使用常规属性访问语法来做到这一点。
请注意,getattr()
它还采用可选的默认值,如果缺少属性,则返回:
>>> x = object()
>>> getattr(x, 'foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
>>> getattr(x, 'foo', 42)
42
使用getattr()
您可以从其他东西中提取属性名称,而不是文字:
for attrname in dir(x):
print('x.{} = {!r}'.format(attrname, getattr(x, attrname))
或者您可以使用setattr()
设置动态属性:
for i, value in enumerate(dynamic_values):
setattr(i, 'attribute{}'.format(i), value)
如果要访问的属性是变量而不是文字字符串,则可以使用它们。它们让您参数化属性访问/设置。
没有理由这样做getattr(x, 'foobar')
,但您可能有一个名为的变量attr
可以设置为“foobar”或“otherAttr”,然后执行getattr(x, attr)
。
另一种情况可能表明它们并不完全相同:
class A:
def __init__(self):
self.__var = 10
setattr(self, '__var2', 100)
a = A()
print(a.__var2)
# 100
print(a.__var)
# AttributeError: 'A' object has no attribute '__var'
至少,setattr
不等同于.
。
我发现当您需要其属性的对象可能是None
. 下面举例说明;
obj = None
attr_val = getattr(obj, 'anyvar', None) #This is not an error.
setattr
和之间有区别.
,尚未记录:
class X:
def __init__(self, value1, value2):
self.__non_private_name_1 = value1
setattr(self, '__non_private_name_2', value2)
>>> x = X('Hi', 'Bye')
>>> x.__dict__
{'_X__non_private_name_1': 'Hi', '__non_private_name_2': 'Bye'}
后一种,当用于设置 dunder 值(带有双下划线的值)时,将单个下划线_
+ self.__class__.__name__
(ie X
) 添加到右侧字符串的开头,.
并设置使用结果字符串 (ie ) 命名的属性_X__non_private_name_1
。