@classmethod
class A: __count = 0 #隐藏count属性 def __init__(self,name): self.name = name self.__add_count() #每一次实例化的时候调用私有化__count进行累加 def __add_count(self): #定义一个私有化的方法 A.__count +=1 def show_count(self): #定义一个普通方法 return A.__count #让用户可以从外部查看__count的值 def eat(self): print('%s在吃饭'%self.name) wl = A('wanglan') print(wl.show_count()) wl.eat() #有的时候,在类中会有一种情况,就是这个方法并不需要使用某一个对象的属性,因此,这个方法中的self参数是一个完成无用的参数, #show_count是一个查看类中属性的方法,这样的方法和某一个对象并没有直接联系
在上面代码中,__add_count 方法和show_count方法并没有使用self参数,但是我们给它传了,正常情况下,如果参数不被使用,我们不应该传入改参数,因此这个方法中的self参数是一个完全无用的参数,我们可以直接删除,删除后的报错也只是Pycharm上的语法报错,但是python的语法不希望我们这样做,我们可以使用 @classmethod 装饰器来解决
class A: __count = 0 #隐藏count属性 def __init__(self,name): self.name = name self.__add_count() #每一次实例化的时候调用私有化__count进行累加 @classmethod #被classmethod 装饰器装饰的方法,都用一个默认的参数,这个参数就是当前类 def __add_count(cls): #定义一个私有化的方法 print(cls,A) #两个值相同 cls.__count +=1 # cls 就可以取代A @classmethod def show_count(cls): #定义一个普通方法 return cls.__count #让用户可以从外部查看__count的值 def eat(self): print('%s在吃饭'%self.name) print(A.show_count()) #可以直接调用show_count wl = A('wanglan') print(wl.show_count()) wl.eat() 结果: 0 <class '__main__.A'> <class '__main__.A'> 1 wanglan在吃饭
本质上:一个方法不用对象属性但是使用静态属性 -- 类方法(@classmethod)
某一个方法被创造出来,就是为了对静态变量进行操作,根部不涉及到对象,所以这个方法就应该被定义成:类方法(被@classmethod装饰),调用这个类方法时,可以使用对象调用wl.show_count(),也可以使用类调用 A.show_count(),但是这个方法的默认参数永远是当前类的命名空间,而不是对象
@staticmethod
def login(): #普通函数 pass login() #调用
纯面向对象编程
class User(object): @staticmethod def login(): #是User类中的名字 函数的名字 login就是一个类中的静态方法,本质上就是一个函数 pass ret = User.login()
如果一个类中的方法不用对象属性也不用静态熟属性 -- 静态方法(@staticmethod),实际上这个方法就是一个普通的函数
小结
普通的方法 类方法 静态方法 默认参数 self cls 无 操作的变量 操作对象的属性 操作静态属性 既不操作对象属性,也不操作类的属性 所属的命名空间 类 类 类 调用方式 对象 类/对象 类/对象 对应的装饰器 无 @classmethod @staticmethod
@property:
把一个方法伪装成属性,和调用属性一样去调用方法()名称装饰,动词就不用了)
某一个属性如果是通过计算得来的,那么计算的过程写在方法里,把这个方法伪装成属性
from math import pi class Circle: def __init__(self,r): self.r = r @property # 把一个方法伪装成属性 源码中有人写, def area(self): # 被property装饰器装饰的方法不能传递除self以外的参数 return pi*self.r**2 @property def perimeter(self): return self.r*pi*2 c1 = Circle(5) # print(c1.area()) #加入@property 方法前的调用 print(c1.area) #加入@property 方法后的调用 c1.r = 10 print(c1.area)
某一个属性需要被私有化,又需要能被外部查看,这种情况,把这个属性通过方法返回,方法伪装成属性
class Person: def __init__(self,name): self.__name = name # 不让外面随便修改 @property def name(self): return self.__name wl = Person('wanglan') print(wl.name)
修改属性值
class Person: def __init__(self,name): self.__name = name # 不让外面随便修改 @property def name(self): return self.__name @name.setter # 之前必须有一个同名的方法被property装饰过 def name(self,new_name): if type(new_name) is str: self.__name = new_name @name.deleter def name(self): del self.__name wl= Person('wang') print(wl.name) wl.name = 'wanglan' print(wl.name) del wl.name # 只是相当于调用被deleter装饰的方法,并不相当于删除name属性 print(wl.name)