【问题标题】:obj.count = 8 or setattr(obj, 'count', 8)obj.count = 8 或 setattr(obj, 'count', 8)
【发布时间】:2013-11-11 15:34:35
【问题描述】:

在 python 中。使用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

【问题讨论】:

    标签: python oop methods var


    【解决方案1】:

    他们确实做同样的事情,但是你不能使用属性设置语法的变量,而你可以使用setattr()来做到这一点。

    换句话说,这是可行的:

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

    但这不是:

    foo = 'count'
    x.foo = 2
    

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

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

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

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

    【讨论】:

      【解决方案2】:

      正如其他人所提到的,它们本质上是相同的。但是,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 的这个“特性”(提示:你可能不应该)是另​​一个问题。

      【讨论】:

        【解决方案3】:

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

        给定

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

        这是dis 在 Python 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 产生的字节码更少,而且我怀疑它也更快。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-10
          相关资源
          最近更新 更多