如何在Python中引用类中的静态属性?

时间:2014-07-01 08:39:50

标签: python class constructor

我有以下python片段:

class myClass:
    myVar = 'a'

    def __init__(self):
        self.myOtherVar = 'b'
        myVar = 'c'  # Gets assigned but only as a local variable.

    print myVar            # prints 'a' !
    print self.myOtherVar  # says 'self' not found

我的问题是这个; 从myVar内打印myClass的内容和/或从init重新分配内容的正确方法是什么?

3 个答案:

答案 0 :(得分:6)

您遇到的问题是因为您不了解类声明的范围如何工作。类声明在其自己的范围内执行。执行完成后,将创建一个新的类对象,并将获得的范围作为其__dict__附加到类。

注意:类范围是在方法范围内搜索!这意味着当方法定义中时,您必须将类属性引用为MyClass.attribute

例如:

class MyClass:
    var = 1

    # we are executing this code as a single block
    # so you must reference the variable as is usual
    print(var)

    # default values are *not* inside the definition.
    # they are evaluated in the outer scope, so use plain "var" here
    def method(self, a_default=var):
        print(a_default)

    def other_method(self):

        # inside methods you are in a different scope
        print(MyClass.var)

        # equivalent *if* no "var" instance attributes exists
        print(self.var)

注意:由于在执行声明时该类仍然不存在,因此无法MyClass声明的“顶级”引用MyClass

class MyClass:
    var = 1
    print(MyClass.var)   # error: MyClass still doesn't exist.

这样做的副作用是以下代码:

class MyClass:
    x = 1
    results = list(i+x for i in range(10))

产地:

NameError                                 Traceback (most recent call last)
<ipython-input-6-f1d4417b2e52> in <module>()
----> 1 class MyClass:
      2     x = 1
      3     results = list(i+x for i in range(10))
      4 

<ipython-input-6-f1d4417b2e52> in MyClass()
      1 class MyClass:
      2     x = 1
----> 3     results = list(i+x for i in range(10))
      4 

<ipython-input-6-f1d4417b2e52> in <genexpr>(.0)
      1 class MyClass:
      2     x = 1
----> 3     results = list(i+x for i in range(10))
      4 

NameError: name 'x' is not defined

因为生成器表达式(以及python3中的列表推导)实际上被认为是具有自己范围的函数。由于未从内部函数范围搜索类范围,因此无法找到x

您可以使用函数定义和默认值来解决此问题:

class MyClass:
    x = 1
    def _make_results(x=x):
        return list(i+x for i in range(10))
    results = _make_results()
    del _make_results    # otherwise it would be added as a method.
    # or:
    results = (lambda x=x: list(i+x for i in range(10)))()

这通常不是问题,因为类定义很少包含除方法定义和一些常量之外的任何内容。


关于课程范围,已经有一些关于课程的问题:

答案 1 :(得分:0)

self.var将:

  1. var self.__dict__中提供var
  2. self.__class__.__dict__ AttributeError中提供self.__class__.var
  3. myClass
  4. 如果要访问静态变量管道继承,请使用此或myClass。如果扩展myClass.var,子实例将访问子类中的静态变量。

    如果要在{{1}}中访问静态变量,即使从后代调用,也可以使用{{1}}。

    对于重新分配它们,必须在类对象上显式完成,否则赋值只会以实例为目标。

答案 2 :(得分:-3)

class myClass:
    myVar = 'a'

    def __init__(self):
        self.myOtherVar = 'b'

    print myVar  # -> 'a'

    class EmptyClass: pass
    s = EmptyClass()
    __init__(s)

    myVar = s.myOtherVar
    print myVar  # -> 'b'

print myClass.myVar  # -> 'b'