classmethod的使用
python中存在三种方法,分别为常规方法(定义中传入self)、@classmethod修饰的类方法、@staticmethod修饰的静态方法。
一
常规方法定义时需要传入self参数,与类的实例绑定。
也就是说调用时需要先实例化类classA为实例A,然后该实例A才拥有方法,通过A.f()的方式来调用。不能直接用类classA.f()的方式来调用。
二
用@classmethod修饰的方法需要传入cls参数(代表当前类),表示该方法与类绑定(不是实例)
在该函数内部可以调用属于类的专有属性(一般来说定义在__init__外面的属性)。
可以直接用classA.f()来调用,当然也可以直接实例化,通过实例来调用。
三
用@staticmethod修饰的方法不需要传入任何参数
该方法内部不能访问类或者实例的属性,相当于定义在类外面的普通方法。可以直接用A.static_foo()来调用或者通过实例来调用。
@classmethod和@staticmethod的异同
相同点:
- 都可以直接用类名.方法(A.xx())的方式来访问,也可以通过实例来访问
不同点:
- 构造时classmethod需要传入cls参数,staticmethod不需要
- classmethod可以通过cls.来访问类的专有属性,staticmethod不能访问类的属性
- classmethod可以被子类继承,能够判断出是父类还是子类调用
- 使用场景
一:
@classmethod用在构造前交互(即类实例化之前),一般是用来实现特殊的构造函数。
cclass wxpClass:"test classmethod "#类成员变量year,month,day=0,0,0#构造函数def __init__(self,y=0,m=0,d=0) -> None:#初始化对象成员self.year=yself.month=mself.day=d#输出函数def out(self):print("%d-%d-%d"%(self.year,self.month,self.day))@classmethoddef fromString(cls,dayString):y,m,d=dayString.split("-")#cls调用了构造函数date1=cls(int(y),int(m),int(d))#类成员赋值需要用clscls.year=int(y)return date1#使用类方法构造一个date2实例对象
date2=wxpClass.fromString("2024-9-3")
date2.out()
print(date2.__dict__)
print(wxpClass.__dict__)
结果:
024-9-3
{'year': 2024, 'month': 9, 'day': 3}
{'__module__': '__main__', '__doc__': 'test classmethod ', 'year': 2024, 'month': 0, 'day': 0, '__init__': <function wxpClass.__init__ at 0x00A9CDA8>, 'out': <function wxpClass.out at 0x00A9CD60>, 'fromString': <classmethod object
at 0x004FE628>, '__dict__': <attribute '__dict__' of 'wxpClass' objects>, '__weakref__': <attribute '__weakref__' of 'wxpClass' objects>}对象date2的成员year,month,day都被改变了;类成员year已经被改变,month,day并没有改变。
二:某些不与实例交互的方法
不与实例交互就可以完成功能的方法虽然可以通过普通的实例化方法实现
但是实例化之后会浪费更多的时间与空间。
因此使用staticmethod。
ps:staticmethod方法和一个定义在类外面的函数没啥区别,为了美观和整洁才移到函数里面的。