0

在蟒蛇。setattr(object, 'var', value使用和方法有什么区别object.var = value。他们似乎都在做同样的事情

class Something(object):
    pass

x = Something()

setattr(x, 'count', 2) #sets count to be 2
x.count = 3            #sets count to be 3
4

3 回答 3

4

他们确实做同样的事情,但你不能使用属性设置语法的变量,而你可以使用setattr().

换句话说,这有效:

foo = 'count'
setattr(x, foo, 2)

但这不是:

foo = 'count'
x.foo = 2

用于动态setattr()属性设置,其中属性的名称取自变量。用于静态属性,您事先知道名称。object.attributename = value

此外,属性访问语法仅限于正确的 Python 标识符,而setattr()可以使用任何字符串。这意味着您可以使用:

setattr(x, '3 little piggies', 42)

尝试使用静态属性将不起作用,因为 Python 标识符不允许空格,并且不能以数字开头。

于 2013-11-11T15:35:47.920 回答
0

正如其他人所提到的,它们本质上是相同的。但是,setattr(obj, 'attr', value)它更通用,因为它允许您执行通过句法构造无法执行的操作obj.attr = value

>>> class A(object):
...    pass
>>> a = A()
>>> setattr(a, 'foo bar', 5)  # space in the attribute name???
>>> print getattr(a, 'foo bar')
5
>>> a.'foo bar' = 7
  File "<stdin>", line 1
    a.'foo bar' = 7
          ^

SyntaxError:无效的语法

你是否应该利用 Python 的这个“特性”(提示:你可能不应该)是另​​一个问题。

于 2013-11-11T15:41:11.147 回答
0

直接访问x.count会产生更高效的代码,我怀疑这是因为属性访问可以在解析/字节编译时解决。这在循环中可能会特别明显。

给定

def f(): setattr(x, 'count', 2)
def g(): x.count = 3

这是disPython 2.7 上的内容:

>>> dis.dis(f)
  1           0 LOAD_GLOBAL              0 (setattr)
              3 LOAD_GLOBAL              1 (x)
              6 LOAD_CONST               1 ('count')
              9 LOAD_CONST               2 (2)
             12 CALL_FUNCTION            3
             15 POP_TOP
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE
>>> dis.dis(g)
  1           0 LOAD_CONST               1 (3)
              3 LOAD_GLOBAL              0 (x)
              6 STORE_ATTR               1 (count)
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE

所以g产生的字节码更少,我怀疑它也更快。

于 2013-11-11T15:46:17.747 回答