Python 实例方法、类方法、静态方法之间的区别及实例说明
类方法
-
定义:使用装饰器@classmethod。第一个参数为“cls”(也可为self),通过它来传递类的属性和方法(不能传实例的属性和方法,即使第一个参数为self,传递的也是类的属性和方法)
- 被调用:类和实例对象都可以调用类方法,不用传对象名
类名.类方法名(args)
实例名.类方法名(args)
实例方法
-
定义:第一个参数为“self”,通过它来传递实例的属性和方法
传递实例属性和方法调用方式”实例名.实例方法名(args)”,这里参数里不包含对象self或cls
传递类属性和方法调用方式为”类名.实例方法名(类名|实例名, args)”,参数包含对象self或cls
-
被调用:实例和类都能调用(只能由实例对象调用实例方法)
如果实例对象调用时 在参数不传对象,写法为 实例名.实例方法名(args)
如果类对象调用时 在参数里传入对象,写法为 类名.实例方法名(类名|实例名, args)
静态方法
-
定义:使用装饰器@staticmethod。参数可有可无,“self”和“cls”均表示传入的对象;
A)静态方法里不能调用实例属性;
B)可调用类属性,但是方法体中不能使直接使用类或实例的任何属性和方法(可以通过类名来调用,例如 “类名.属性”;)
- 被调用:类和实例对象都可以调用静态方法,跟实例方法调用相同
self和cls 的区别:self是类(Class)实例化对象,cls就是类(或子类)本身,取决于调用的是哪个类。
实例方法调用方式:实例函数需要将实例化对象或者类名称传入 self 对象
实例名.实例方法名(args)
类名.实例方法名(实例名,args)
类名.实例方法名(类名,args)
类名.实例方法名(xx, args) 传入的对象如果为实例对象,则类方法里调用的self.a 或 cls.a为实例变量,无实例变量则用类变量;传入的对象为 类对象,self.a 或cls.a为类变量,没有类变量会报错。
# 实例方法的三种调用方式 class A(object): # 无实例变量,有类变量 a = 'a' def instanceMethod_A(self, name): print('hello', name, self.a) # 如果传入的对象为实例,因为无实例变量,所以self.a为 类变量
class B(object): # 有实例变量,有类变量 a = "b" def __init__(self,b): self.a = b def instanceMethod_B(self, name): print('hello', name, self.a) # 如果传入的对象实例,因为有实例变量,self.a 为实例变量
class C(object): # 无类变量,有实例变量 '''通过 "类.实例方法名(类, "args")" 来调用实例时,会报错没有类属性错误''' # a = "b" def __init__(self,b): self.a = b def instanceMethod_C(self, name): print('hello', name, self.a) # 这里self.a 需根据传入的对象是类 还是 实例决定,如果传入的是类,由于没有类变量,则会报错
a = A() b = B("bb")
a.instanceMethod_A("小熊猫") # hello 小熊猫 # 总结:传入self 的对象为实例a,所以self.a表示实例的变量;如果有实例变量就用实例变量,如果没有实例变量a,就会用类变量 A.instanceMethod_A(a,"小熊猫") # 传入对象为实例,由于无实例变量,self.a 为类变量。 B.instanceMethod_B(b,"小熊猫") # 传入对象为实例,由于有实例变量,self.a 为实例变量 A.instanceMethod_A(A,"小熊猫") # 传入self 的对象为类A,所以self.a表示类变量;如果没有类变量a 则会报错 C.instanceMethod_C(C,"小熊猫") # 传入self 的对象为类C,self.a表示类变量;由于没有类变量a,报错 # hello 小熊猫 a # hello 小熊猫 a # hello 小熊猫 bb # hello 小熊猫 a # 报错
类方法调用方式:参数中 无需传“类对象”或者“实例对象”
类名.类方法名(args)
实例名.类方法名(args)
【类方法的第一个参数为 cls和self 的区别】类方法里只能调用类变量,不能调用实例变量,所以示例中调用的self.name 和 cls.name都表示类变量
# 类方法的调用:参数中不用传递对象,通过类名或对象名调用 class Dog(object): name='SB' #类变量 def __init__(self,name): self.name=name @classmethod #类方法只能访问类变量,不能访问实例变量;这里self.name表示类变量 def eat1(self,name): print('%s is eating %s'%(self.name,name)) # self.name 是类变量 @classmethod #类方法只能访问类变量,不能访问实例变量;这里cls.name表示类变量 def eat2(cls,name): print('%s is eating %s'%(cls.name,name)) # cls.name 是类变量 d=Dog('Lulu') d.eat1('Mantou1') # 参数是self,传输的对象是实例d d.eat2('Mantou2') # 参数是cls,传输的对象是实例d Dog.eat1("Mantou3") # 参数是self,传输的对象是类D Dog.eat1("Mantou4") # 参数是cls,传输的对象是类D d.talk("nothing") ''' >>>>>> SB is eating Mantou1 SB is eating Mantou2 SB is eating Mantou3 SB is eating Mantou4 Lulu is talking nothing '''
静态方法调用方式:如果传入对象,则属性根据传入对象决定
实例名.静态方法名(args) 或 实例名.静态方法名(objectName, args)
类名.静态方法名(args) 或 类名.静态方法名(objectName, args)
【说明】类名.静态方法名(objectName, args) 传入的对象如果为实例对象,则类方法里调用的self.a 或 cls.a 为实例变量,无实例变量则用类变量;传入的对象为 类对象,self.a 或 cls.a 为类变量,没有类变量会报错。
# 静态方法调用 class A(object): # 无类变量,有实例变量 # a = '「调用类属性a」' def __init__(self): self.a = "「调用实例属性a」" @staticmethod def hasObjectSelf(self,name): print('hello', name, self.a) # self.a 根据传入对象决定,传入类,则为类属性,传入实例,则为实例属性; @staticmethod def hasObjectCls(cls, name): print('hello', name, cls.a) # cls.a 根据传入对象决定,传入类,则为类属性,传入实例,则为实例属性; class B(object): # 有类变量,无实例变量 b = '「调用类属性b」' @staticmethod def noObject(name): print('hello', name, B.b) # 调用类属性需要通过 “类名.属性名” @staticmethod def hasObjectSelf(self,name): # self print('hello', name, B.b, self.b) # self.a 根据传入对象决定,传入类,则为类属性,传入实例,则为实例属性; @staticmethod def hasObjectCls(cls, name): print('hello', name, B.b, cls.b) # cls.a 根据传入对象决定,传入类,则为类属性,传入实例,则为实例属性; a = A() b = B() # 不用传入对象,实例和类分别调用静态方法 b.noObject("小熊猫") # hello 小熊猫 「调用类属性b」 B.noObject("小熊猫") # hello 小熊猫 「调用类属性b」 # 需传入对象,传入对象分别为实例和类 a.hasObjectSelf(a, "小熊猫aa") # 传入的对象为实例,由于有实例,则self.a为实例属性 # a.hasObjectSelf(A, "小熊猫aa") # 传入的对象为类变量,由于没有类,报错 # 需传入对象,传入对象分别为实例和类 A.hasObjectCls(a, "小熊猫aa") # 传入的对象为实例,由于有实例,则self.a为实例属性 # A.hasObjectCls(A, "小熊猫aa") # 传入的对象为类,由于没有类变量,报错 # 需传入对象,传入对象分别为实例和类 B.hasObjectSelf(b, "小熊猫bb") # 传入的对象为实例,由于没有实例,则self.a为类属性 B.hasObjectSelf(B, "小熊猫bb") # 传入的对象为类,则self.a为类属性 ''' hello 小熊猫 「调用类属性b」 hello 小熊猫 「调用类属性b」 hello 小熊猫aa 「调用实例属性a」 hello 小熊猫aa 「调用实例属性a」 hello 小熊猫bb 「调用类属性b」 「调用类属性b」 hello 小熊猫bb 「调用类属性b」 「调用类属性b」 '''
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步