42

通过阅读文档,我完全了解getattr()setattr()的作用。但它也明确表示getattr(x, 'foobar')等价于x.foobarsetattr(x, 'foobar', 123)等价于x.foobar = 123

那么我为什么要使用它们呢?

4

5 回答 5

61

因为您也可以使用动态变量:

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)
于 2013-10-01T18:53:03.017 回答
10

如果要访问的属性是变量而不是文字字符串,则可以使用它们。它们让您参数化属性访问/设置。

没有理由这样做getattr(x, 'foobar'),但您可能有一个名为的变量attr可以设置为“foobar”或“otherAttr”,然后执行getattr(x, attr)

于 2013-10-01T18:53:17.153 回答
5

另一种情况可能表明它们并不完全相同:

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不等同于.

于 2018-07-15T10:26:11.760 回答
1

我发现当您需要其属性的对象可能是None. 下面举例说明;

obj = None
attr_val = getattr(obj, 'anyvar', None) #This is not an error.
于 2018-07-05T08:34:39.083 回答
0

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

于 2021-12-06T19:11:24.223 回答