实例方法、类方法和静态方法是Python在使用过程中必须掌握的三大类型方法,为帮助各位小伙伴能快速的入门,由我煞费苦心整理以下文档,若对你有帮助,请点赞、评论和收藏哦!!
在了解实例方法、类方法和静态方法之前,我们应该先理解方法的基本概念,下面用简单的例子进行解释。
方法
- 描述一个目标的行为动作;比如描述一个人怎么吃、怎么喝、怎么玩。
- 和函数非常相似,都封装了一系列行为动作;都可以被调用之后,执行一系列行为动作;最主要的区别就是:调用方式
# -----------------------------------方法--------------------------------
class Person:
def eat(self):
print("在吃饭")
def play(self):
print("在玩耍")
p = Person() # 实例化
p.eat() # 调用方法
p.play() # 调用方法
# ---------------------------------函数-----------------------------------------
def eat():
print("在吃饭")
def play():
print("在玩耍")
eat() # 直接调用函数
play() # 直接调用函数
方法的划分
- 实例方法:默认第一个参数接受到一个实例
- 类方法:默认第一个参数需要接受到一个类
- 静态方法:第一个参数默认不接受参数
主要依据:
- 划分的依据是:方法的第一个参数必须要接受的数据类型
实例方法默认接受self
实例,类方法默认接受cls
类,静态方法不接任何参数
# -----------------------------------实例方法、类方法和静态方法------------------------------
class Person:
def shilifangfa(self):
print("这是一个实例方法", self)
@classmethod
def leifangfa(cls):
print("这是一个类方法", cls)
@staticmethod
def jingtaifangfa():
print("这是一个静态方法")
p = Person()
print(p)
p.shilifangfa()
Person.leifangfa()
Person.jingtaifangfa()
结果
<__main__.Person object at 0x0000019C4DE13EB0>
这是一个实例方法 <__main__.Person object at 0x0000019C4DE13EB0>
# 解释:类属性地址和实例方法的地址相同,说明在调用的内容相同,因此,可以确定p就是Person传入的实例,将self对应的即为实例p,Person object 说明是 Person对应的一个实例
这是一个类方法 <class '__main__.Person'>
# 解释:Person作为了leifangfa中的cls传入
这是一个静态方法
# 解释:并不需要任何参数传入
与类属性和实例属性不同,方法属于存储层面,一个属性隶属于一个实例就称为实例属性,隶属于类就称为类属性。
- 不管哪一种类型的方法,都是存储在类当中,没有在实例当中
例子
class Person:
def shilifangfa(self):
print("这是一个实例方法", self)
@classmethod
def leifangfa(cls):
print("这是一个类方法", cls)
@staticmethod
def jingtaifangfa():
print("这是一个静态方法")
p = Person()
print(p.__dict__) # 查看p对象中的字典
print(Person.__dict__) # 查看类对象中的字典
def run():
pass
# p.func = run # 函数也是对象
p.age = 18
print(p.__dict__)
结果
{}
# 说明在实例对象中并没有存储任何的内容
{'__module__': '__main__', 'shilifangfa': <function Person.shilifangfa at 0x00000257D253F310>, 'leifangfa': <classmethod object at 0x00000257D23F54F0>, 'jingtaifangfa': <staticmethod object at 0x00000257D247FC70>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
# 所有的类型的方法均存储在类当中,反映到内存中也是存储在字典里面。
{'age': 18}
- 不同类型方法的调用方式不同
不管是自己传递,还是解释器帮我们处理;最终要保证不同类型的方法第一个参数接收到的数据,是正确的类型
使用
掌握:
- 语法
- 不同类型的方法的原则
- 不同类型方法的调用
- 根据不同的问题,自己决定到底该设计怎样的方法来解决问题
在学习完上面的基础知识后,我们对不同的重点方法进一步解释:
实例方法
默认第一个参数需要接受到一个实例
class Person:
def eat(self, method): # 实例方法self是形参名称,规范要求,可以改变,新增加参数可以写在self后
print("这是一个实例方法", method,self)
p = Person('Eat')
p.eat()
标准调用
- 使用实例调用实例方法:不用手动传,解释器会自动把调用对象本身传递过去
- 如果实例方法没有接受任何参数,则会报错(解释器自动传,但是没有对应参数)
其他调用(了解)
本质:找到函数本身来调用(存在类对象的字典中)
- 使用类调用
class Person:
def eat(self, food):
print("在吃饭", self, food)
print(Person.eat)
Person.eat(123, '土豆')
- 间接调用
class Person:
def eat(self, food):
print("在吃饭", self, food)
print(Person.eat)
func = Person.eat
func(123, '土豆')
类方法
默认第一个参数需要接受到一个类
class Person:
@classmethod #装饰器:在保证原本函数不改变的前提下,直接给这些函数增加一些功能
def leifangfa(cls, a):
print("这是一个类方法", cls, a)
# 方式1
Person.leifangfa(123)
# 方式2
p = Person() # 将实例所对应的类传递给leifangfa,本质都是传递class
p.leifangfa(666)
# 方式3
func = Person.leifang
func(111)
以上例子可以直接反映类方法,但若有进一步的需要,建议Ctrl
+鼠标左键点击classmethod
看具体文档说明,很全很详细!
静态方法
无参数传递
class Person:
@staticmethod
def jingtaifangfa():
print('这是一个静态方法')
# 调用方法1
Person.jingtaifangfa()
# 调用方法2
p = Person()
p.jingtaifangfa()
# 调用方法3
func = Person.jingtaifangfa()
func
- 静态方法无需传入self参数,类成员方法需传入代表本类的cls参数
- 从第1条,静态方法是无法访问实例变量的,而类成员方法也同样无法访问实例变量,但可以访问类变量
- 静态方法有点像函数工具库的作用,而类成员方法则更接近类似Java面向对象概念中的静态方法
三种方法的访问权限问题
对于类中的实例方法、类方法和静态方法访问权限问题,进行实例分析:
class Person:
age = 18
def shilifangfa(self):
print(self)
print(self.age)
print(self.num)
@classmethod
def leifangfa(cls):
print(cls)
print(cls.age)
print(cls.num)
@staticmethod
def jingtaifangfa():
print(Person.age)
# print(Person.num) # 没有访问权限
# 实例访问权限
p = Person() # 定义实例
p.num = 10
p.shilifangfa() # 访问实例方法和类方法
p.jingtaifangfa() # 访问静态方法
# 结果均可访问
# 类访问权限
print(Person.age) # 访问类属性:no problem
# Person.shilifangfa() # 访问实例方法, 没有访问权限
Person.jingtaifangfa() # 访问静态方法,no problem
# 静态方法权限:直接在静态方法里面定义即可
Person.jingtaifangfa()
# 访问类属性可以,实例属性没有访问权限
进一步解释,实例方法的访问必须基于实例,因此,通过直接访问实例方法,会产生实例报错,换句话说,一个实例方法只有一个类,但是一个类下有很多的实例,如果不指定一个实例,是无法访问实例方法的,静态方法主要依据类方法可以调用类属性,也是同样的道理。
总结为下表所示:
名称 | 访问权限 |
---|---|
类 | 类属性+静态方法 |
实例 | 类属性+实例属性 |
静态方法 | 类属性 |
因此,实例的访问权限最大,类和静态方法的访问权限局限于类本身内容中。
看到这里的YOUR,有所收获吗?如有疑问,可评论哦,博主看到第一时间回复你,若没疑问,可否点赞加收藏呢?原创不易!!!