类属性和对象属性的定义
class LearnClass(): #类属性 cls_attr = None def __init__(self,arg): #对象属性 self.obj_attr = arg object = LearnClass("test")
特性:对象的属性不能通过类来访问,类的属性可以通过对象来读,一但对象进行类属性的写操作时就是对象自己有了复制了这个属性的副本到对象自己。
通过类进行类属性的访问
LearnClass.cls_attr #通过类访问进行读写都可以且修改对于这个类及类的对象(读)都立马可见 print(object.cls_attr) #仅能读,一旦对象写这个属性就是先复制一个副本到对象自己然后写自己的副本
代码验证
class learn_cls(): cls_attr = 0 def __init__(self,objname,id): self.name = objname self.obj_attr = id def show(self): print(("%s cls_attr = "% self.name),self.cls_attr) print("cls_attr= ",learn_cls.cls_attr) print(("%s cls_attr AT: "% self.name),id(self.cls_attr)) print("cls_attr AT: ",id(learn_cls.cls_attr)) obj1 = learn_cls("obj1","1") obj2 = learn_cls("obj2","2") print("-----------------------------------------") obj1.show() print("=========================================") obj2.show() print("-----------------------------------------") print("--------------------Write----------------") learn_cls.cls_attr = 2 obj1.show() obj2.show() print("=========================================") obj1.cls_attr = 3 obj1.show() print("=========================================") obj2.cls_attr = 4 obj2.show() print("-----------------------------------------") #run ouput """ ----------------------------------------- obj1 cls_attr = 0 cls_attr= 0 obj1 cls_attr AT: 8791389037360 #注意这里的输出1 cls_attr AT: 8791389037360 ========================================= obj2 cls_attr = 0 cls_attr= 0 obj2 cls_attr AT: 8791389037360 #注意这里的输出2 cls_attr AT: 8791389037360 ----------------------------------------- --------------------Write---------------- obj1 cls_attr = 2 cls_attr= 2 obj1 cls_attr AT: 8791389037424 cls_attr AT: 8791389037424 obj2 cls_attr = 2 cls_attr= 2 obj2 cls_attr AT: 8791389037424 cls_attr AT: 8791389037424 #这里的打印说明对类属性访问对与类的对象是全部立马可见的 ========================================= obj1 cls_attr = 3 cls_attr= 2 obj1 cls_attr AT: 8791389037456 cls_attr AT: 8791389037424 #这里已经可以说明通过类的对象访问类的属性的时候,已经是访问的是类自己的副本了 ========================================= obj2 cls_attr = 4 cls_attr= 2 obj2 cls_attr AT: 8791389037488 cls_attr AT: 8791389037424 ----------------------------------------- """
通过上面的实际测试,测试环境是python3.7,win64。通过实际运行测试最终结果验证了前面说的结论,可以按Linux的写时复制来理解。
类的方法和对象的方法和静态方法
定义
class B(object): #类方法 @classmethod def fun1(cls): print("cls method") #静态方法 @staticmethod def fun2(): print('staticmethod') #对象方法 def fun3(self,y): self.x+=y
实例方法(对象方法)隐含的参数为类实例self,而类方法隐含的参数为类本身cls。 静态方法无隐含参数,使用装饰器将方法定义为静态方法主要为了类实例也可以直接调用此方法。所以逻辑上,类方法被类调用也可以被类实例调用,实例方法被实例调用,静态方法两者都能调用。主要区别在于参数传递上的区别,实例方法悄悄传递的是self引用作为参数,而类方法悄悄传递的是cls引用作为参数。实例方法(普通方法)应该由实例调用类不能调用;类方法可以由类调用,而且因为传入了参数cls,故也可以由实例来调用;静态方法两者都能调用。