How to reference a static attribute from within a class in Python?
我有以下python片段:
1 2 3 4 5 6 7 8 9 | 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 |
我的问题是:从EDOCX1×1中打印EDCOX1 0内容的正确方法是什么?和/或重新分配它们从EDCOX1到2?
您面临的问题是,您不了解类声明的作用域是如何工作的。类声明在其自身的范围内执行。执行完成后,将创建一个新的类对象,并将获得的作用域作为其
注意:在方法范围内不搜索类范围!这意味着您必须在方法定义中引用类属性作为
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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) |
注:由于该类在执行其声明时不存在,因此不能在
1 2 3 | class MyClass: var = 1 print(MyClass.var) # error: MyClass still doesn't exist. |
这样做的一个副作用是,以下代码:
1 2 3 | class MyClass: x = 1 results = list(i+x for i in range(10)) |
生产:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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中的列表理解)实际上被视为具有自己范围的函数。由于没有从内部函数范围中搜索类范围,因此找不到
您可以使用函数定义和默认值来绕过此问题:
1 2 3 4 5 6 7 8 | 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)))() |
这通常不是问题,因为类定义很少包含方法定义和一些常量以外的任何内容。
关于类范围,已经有一些关于so的问题:
- 类块中定义的名称范围没有扩展到方法的块。为什么会这样?
- 范围界定规则的简短描述?
- 嵌套类的作用域?
- python类中的变量范围
- 为什么静态绑定对于类和函数的工作方式不同?
因此,如果您想访问静态变量挖掘继承,请使用此或EDCOX1 6。如果扩展EDCOX1(7),则子实例将访问子类中的静态变量。
如果您想访问EDCOX1中7的静态变量,即使从子代调用,也可以使用EDCOX1(9)。
至于重新分配它们,必须明确地在类对象上完成,或者赋值将只针对实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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' |