探讨Python的类属性和实例属性
如果你曾经是一个C++/Java语言开发者,那么面对Python语言的类属性和实例属性,会感觉莫名奇妙的,下面给出我的理解和一些其他网友总结.
代码1
class AAA():
aaa = 10
# 情形1
obj1 = AAA()
obj2 = AAA()
print obj1.aaa, obj2.aaa, AAA.aaa # 输出 10, 10, 10
# 情形2
obj1.aaa += 2
print obj1.aaa, obj2.aaa, AAA.aaa # 输出 12, 10, 10
# 情形3
AAA.aaa += 3
print obj1.aaa, obj2.aaa, AAA.aaa # 输出 12, 13, 13
问: 因为aaa属性被称为类属性,既然是类属性,那么根据从C++/Java这种静态语言使用的经验来判断,类属性应该是为其实例所共享的。那么从类的层次改变aaa的值,自然其实例的aaa的值也应该变化?
代码2
class JustCounter:
__secretCount = 0
def countObjectSecretCount(self):
self.__secretCount += 1
@staticmethod
def countClassSecretCount():
JustCounter.__secretCount += 1
def printObjectSecretCount(self):
print "属性: ", self.__secretCount
@staticmethod
def printClassSecretCount():
print "类的属性: ", JustCounter.__secretCount
counter1 = JustCounter()
counter2 = JustCounter()
counter1.countObjectSecretCount() # counter1.__secretCount = 1, JustCounter.__secretCount = 0, counter2没有属性: __secretCount
JustCounter.countClassSecretCount() # counter1.__secretCount = 1, JustCounter.__secretCount = 1, counter2没有属性: __secretCount
counter2.countObjectSecretCount() # counter1.__secretCount = 1, JustCounter.__secretCount = 1, counter2.__secretCount=2
print "对象1的", counter1.printObjectSecretCount() # 输出: 对象1的属性: 1
print JustCounter.printClassSecretCount() # 输出: 类的属性: 1
print "对象2的", counter2.printObjectSecretCount() # 输出: 对象2的属性: 2
# 动态的加属性
counter1.name = "thinking_fioa"
print counter1.name # 输出: thinking_fioa
JustCounter
|
-----------
| |
counter1 counter2
解释:
- 首先:self.__secretCount += 1,可以理解为三个步骤: 取值,加操作,赋值操作
- counter1.countObjectSecretCount()代码中: counter1没有__secretCount这个属性,所以它向上找到JustCounter类,成功找到,执行 +1,然后为对象counter1添加属性并赋值__secretCount = 1。
- JustCounter.countClassSecretCount()代码: 仅仅为JustCounter.__secretCount = 1
- counter2.countObjectSecretCount()代码中: counter2没有__secretCount这个属性,所以它向上找到JustCounter类,成功找到,执行 +1,然后为对象counter2添加属性并赋值__secretCount = 2。
总结:
- Python的类属性和实例属性与Java的完全不同。python是一个动态语言,我们不能用Java语言的类属性来理解Python的类属性。
- 理解Python属性需要依赖查找树来理解。从下往上查找机制
- Python是动态语言,可以动态添加和删除属性