实例方法、类方法和静态方法区别和联系

  实例方法、类方法和静态方法是Python在使用过程中必须掌握的三大类型方法,为帮助各位小伙伴能快速的入门,由我煞费苦心整理以下文档,若对你有帮助,请点赞、评论和收藏哦!!

  在了解实例方法、类方法和静态方法之前,我们应该先理解方法的基本概念,下面用简单的例子进行解释。

方法

  1. 描述一个目标的行为动作;比如描述一个人怎么吃、怎么喝、怎么玩。
  2. 和函数非常相似,都封装了一系列行为动作;都可以被调用之后,执行一系列行为动作;最主要的区别就是:调用方式

# -----------------------------------方法--------------------------------
class Person:

    def eat(self):
        print("在吃饭")

    def play(self):
        print("在玩耍")


p = Person() # 实例化
p.eat() 	 # 调用方法
p.play()	 # 调用方法

# ---------------------------------函数-----------------------------------------

def eat():
    print("在吃饭")

def play():
    print("在玩耍")

eat()		# 直接调用函数
play()		# 直接调用函数

方法的划分

  1. 实例方法:默认第一个参数接受到一个实例
  2. 类方法:默认第一个参数需要接受到一个类
  3. 静态方法:第一个参数默认不接受参数

主要依据:

  • 划分的依据是:方法的第一个参数必须要接受的数据类型
    实例方法默认接受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}
  • 不同类型方法的调用方式不同
    不管是自己传递,还是解释器帮我们处理;最终要保证不同类型的方法第一个参数接收到的数据,是正确的类型

使用

  掌握:

  1. 语法
  2. 不同类型的方法的原则
  3. 不同类型方法的调用
  4. 根据不同的问题,自己决定到底该设计怎样的方法来解决问题

  在学习完上面的基础知识后,我们对不同的重点方法进一步解释:

实例方法

  默认第一个参数需要接受到一个实例

class Persondef 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
  1. 静态方法无需传入self参数,类成员方法需传入代表本类的cls参数
  2. 从第1条,静态方法是无法访问实例变量的,而类成员方法也同样无法访问实例变量,但可以访问类变量
  3. 静态方法有点像函数工具库的作用,而类成员方法则更接近类似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,有所收获吗?如有疑问,可评论哦,博主看到第一时间回复你,若没疑问,可否点赞加收藏呢?原创不易!!!

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting_1997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值