里面提到了python类中的变量包括下面两类:类变量,实例变量。
其中,“类变量”在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
坦白讲,第一次看了后有点懵,一直以为class中定义的所有变量,都是python对象所独有的。
但其实, “类变量”有点像C#或者java中,静态(static)变量,所有的类的“类变量”都是相同的。但是“实例变量”才是跟着一个个对象独有的变量。这像下面所说:
当我看了网上的文档自以为搞懂了的时候,亲自coding了以下,发现和网上大家的说法并不一致。
上面那张图说法有点狭隘了!
可以参照下面的代码:
class testclass: classV1='Lisa' def __init__(self,objectName,age): self.name1=objectName self.age=agetc1=testclass('Peter',20)tc1.__class__.classV1='Harry'print(tc1.__class__.classV1)tc2=testclass('Mary',30)print(tc2.__class__.classV1)print(tc1.__class__.classV1)
上面明确修改了类的"类变量"(.__class__.classv1),我们可以看到整个类的都发生了变化,因此返回值为:
HarryHarryHarry
但是,当我们把__class__去掉,直接修改:
class testclass: classV1='Lisa' def __init__(self,objectName,age): self.name1=objectName self.age=agetc1=testclass('Peter',20)#tc1.__class__.classV1='Harry'tc1.classV1='Harry'print(tc1.__class__.classV1)tc2=testclass('Mary',30)print(tc2.__class__.classV1)print(tc1.__class__.classV1)
可以发现,类变量并没有被修改,上面代码的结果都是Lisa,如果我们多打印两行:
class testclass: classV1='Lisa' def __init__(self,objectName,age): self.name1=objectName self.age=agetc1=testclass('Peter',20)#tc1.__class__.classV1='Harry'tc1.classV1='Harry'#print(tc1.__class__.classV1)tc2=testclass('Mary',30)print(tc2.__class__.classV1)print(tc2.classV1)print(tc1.__class__.classV1)print(tc1.classV1)
其结果是:
LisaLisaLisaHarry
当然上面的操作,我们也可以直接对这个static class进行修改,也全部正确修改类变量:
testclass.classV1='Harry'
所以我们发现,即使是以类变量的形式,声明在class中,但实际运行过程中,python还是会对每个对象,建立自己的“实例变量”。
只有在明确调用.__class__.进行修改的时候,才会执行其“类变量”。
这一点和网上大部分的解释不同,相信是python的新版本进行的修改,而这样修改后也和大部分的面向对象语言更加接近了。