我读here表示类变量在方法参数列表的范围内。要在那里使用类变量,我应该将其称为counter
而不是MyClass.counter
,因为该类正处于定义的中间,但是我可以在MyClass.counter
中将其作为__init__
方法。这是否意味着在__init__
方法内部完全定义了类?
编辑:我还想知道为什么counter
在方法的参数列表范围内而不在方法体中?
class MyClass(object):
counter = 0
def __init__(self): # counter is in scope here. can be used as default argument
counter += 1 # Counter not in scope. Throws UnboundLocalError
def printCount(self):
print counter # Counter not in scope. Throws UnboundLocalError
答案 0 :(得分:8)
在方法中,您可以通过两种不同的方式访问类属性:
通过引用该类,然后是属性:
MyClass.counter
通过访问实例上的属性self
:
self.counter
仅当没有实例属性屏蔽counter
时才有效。
问题是,当您设置实例上的属性时,self
上无法再访问类属性:
self.counter += 1
首次运行时会设置一个实例属性,不再访问class属性。
如果你想设置一个类属性,你将不得不使用第一种方法来解决它:
class MyClass(object):
counter = 0
def __init__(self):
MyClass.counter += 1
def printCount(self):
# these both work:
print self.counter
print MyClass.counter
您无法在方法中将counter
称为本地。在类定义主体之外,它们不是本地或全局名称。只有在class
body内才可以这样做:
然后使用新创建的本地命名空间和原始全局命名空间,在新的执行框架 [...] 中执行类的套件。 (通常,套件仅包含函数定义。)当类的套件完成执行时,其执行帧将被丢弃,但其本地名称空间将被保存。 [...]然后使用基类的继承列表和属性字典的已保存本地名称空间创建类对象。
换句话说,当Python执行class
主体时,counter
和__init__
和printCount
是本地名称,并且在执行期间您可以将这些名称称为当地人。因此,您可以使用counter
为方法参数定义默认值,或者对其进行基础计算。但是一旦构造了类,那个名称空间就会消失,你将不得不引用MyClass.<name>
。
答案 1 :(得分:1)
这是另一个简单的解释:
<强> 1。类变量是否在为Python类定义的方法的范围内?
以下是类变量说明:
注意:类变量存储在class_name.__dict__
中,即共享给所有实例。
注意:实例变量存储在instance.__dict__
中,即仅存储在当前实例中。
注意:使用类名访问类变量总是一个好主意,以减少混淆,而不是用实例变量重写。
以下是摘录:
class ClassA(object):
_counter = 0
def __init__(self, val):
self._counter = val
def show_me(self):
print 'Class variable: %d' % ClassA._counter
print 'Instance variable: %d' % self._counter
obj = ClassA(1000)
obj.show_me()
print ClassA.__dict__['_counter']
print obj.__dict__['_counter']
输出:
Class variable: 0
Instance variable: 1000
0
1000
<强> 2。如何在方法(类方法或实例方法或静态方法)中访问类变量并可能更改它?
您可以使用class_name点变量名称访问类变量,即
ClassA._counter
第3。什么是最好的方式?例如,我可能想要计算已经创建了多少个类的实例。
到目前为止,我知道覆盖__new__
方法会更好,因为__new__
正在调用每个对象创建和更新类变量_counter
,如下面的代码段所示:
#!/usr/bin/python
class ClassA(object):
# this _counter is in the class.__dict__ which shared across all instance
_counter = 0
def __new__(cls, *args, **kw):
ob = super(ClassA, cls).__new__(cls, *args, **kw)
ClassA._counter += 1
return ob
def __init__(self, val):
# this _counter is in the instance dictionary which is not shared
self._counter = val*val
def total_instance(self):
return ClassA._counter
# Lets create three instance
for i in range(1,4):
obj = ClassA(i)
print 'class variable _counter : %d' % obj.total_instance()
print 'instance variable _counter : %d' % obj._counter
输出:
class variable _counter : 1
instance variable _counter : 1
class variable _counter : 2
instance variable _counter : 4
class variable _counter : 3
instance variable _counter : 9
注意:在上面的示例中,我试图向您展示实例变量_counter
和类变量_counter
的区别。
如果有帮助,请告诉我。