python-面向对象编程-实例方法、静态方法、类方法

python-面向对象编程-实例方法、静态方法、类方法,第1张

实例方法举例

class Girl:
    def __init__(self, name, age):
        print("自动调用构造方法")
        self.name = name
        self.age = age

    def hello(self):
        print("一个实例方法,需要通过对象调用")
        print("my name is :", self.name, " and my age is :", self.age)


girl = Girl('小萝莉', 5)
girl.hello()

运行结果

自动调用构造方法
一个实例方法,需要通过对象调用
my name is : 小萝莉  and my age is : 5

Process finished with exit code 0
  • 最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)
  • 实例方法通常会用实例对象直接调用
    通过类名调用实例方法
    Python 也支持通过类名调用实例方法,但需要手动给 self 参数传实例对象
girl = Girl('小少女', 18)
Girl.hello(girl)

运行结果

自动调用构造方法
一个实例方法,需要通过对象调用
my name is : 小少女  and my age is : 18

Process finished with exit code 0

==============================================
类方法
类方法与实例方法的相同点和不同点

  • 相似点

也至少要包含一个参数,不过通常命名为 cls
在调用类方法时,无需显式为 cls 参数传参,但传递的并不是实例对象,而是类对象本身

  • 不同点

最大的不同在于需要使用 @classmethod 装饰器才能称为类方法

举例

 class Girl:
    # 类属性
    age = 18

    # 类方法, 添加装饰器
    @classmethod
    def class_func(cls):
        print("class_func cls 对象的 id ", id(cls))
        cls.age += 1
        print("类属性 sum ", cls.age)

    @classmethod
    def class_func_twi(cls):
        print("class_func_twi cls 对象的 id ", id(cls))
        cls.age += 2
        print("类属性 sum ", cls.age)


Girl.class_func()
Girl.class_func_twi()

运行结果

class_func cls 对象的 id  2209291989328
类属性 sum  19
class_func_twi cls 对象的 id  2209291989328
类属性 sum  21

Process finished with exit code 0

cls 代表的是同一个对象,类对象

类方法可以调用实例方法吗?
可以,但有局限性

class Girl:
    # 类属性
    age = 18

    def __init__(self, age):
        self.age = age

    def hello(self):
        print("一个实例方法,需要通过对象调用")
        print("my age is :", self.age)

    # 类方法, 添加装饰器
    @classmethod
    def class_func(cls):
        print("class_func cls 对象的 id ", id(cls))
        print("类属性 sum ", cls.age)
        cls.hello(cls)


Girl.class_func()

运行结果

class_func cls 对象的 id  2264646001136
类属性 sum  18
一个实例方法,需要通过对象调用
my age is : 18

Process finished with exit code 0
  • 类方法调用实例方法的方式: cls.实例方法(cls) ,通过 cls 调用,且还要传递 cls 为参数
  • 从 id相同即可看出,实例方法接收的仍然是一个类对象

实例对象可以调用类方法吗?
可以,但不建议

girl = Girl(5)
girl.class_func()
class_func cls 对象的 id  1612183736016
类属性 sum  18
一个实例方法,需要通过对象调用
my age is : 18

Process finished with exit code 0

  • girl 是一个实例对象,且初始化赋值了 age 实例属性
  • 但最后实例方法打印的仍然是 sum 类属性,表明类方法无法访问实例属性
  • 且 cls、self 参数的 id
    和上面的栗子完全一样,表明即使通过实例对象调用类方法,传递的仍然是类对象的引用,所有类方法都被同一个类对象调用,一个类只有一个类对象

实例方法可以调用类属性吗?
可以、但不能通过实例对象调用,只能通过类对象

 class Girl:
    # 类属性
    age = 18

    def __init__(self, age):
        self.age = age

    def hello(self):
        print("一个实例方法,需要通过对象调用")
        print("my age is :", self.age)
        print("调用类属性,类名.属性")
        print(f'类属性里面的age属性{Girl.age}')


girl = Girl(5)
girl.hello()

运行结果

一个实例方法,需要通过对象调用
my age is : 5
调用类属性,类名.属性
类属性里面的age属性18

Process finished with exit code 0

====================================================
静态方法

  • 和之前学过的函数一毛一样,唯一区别是:静态方法需要定义在类体中,且需要添加 @staticmethod 装饰器
  • 静态方法没有 self、cls 参数,也不需要至少传一个参数,和普通函数一样
  • Python解释器不会对它包含的参数做任何类或对象的绑定,所以静态方法无法调用任何类属性、类方法、实例属性、实例方法,
  • 除非通过类名和实例对象

什么时候会用静态方法
类里面封装的方法

  • 既不需要访问实例属性、实例方法
  • 也不需要访问类属性、类方法

就可以考虑将这个方法封装成一个静态方法
举个例子

class Girl:
    # 类属性
    age = 5

    def __init__(self, age):
        self.age = age

    def hello(self):
        print("一个实例方法,需要通过对象调用")
        print("my age is :", self.age)

    @classmethod
    def play_game(cls):
        print('一个类方法,玩游戏')

    @staticmethod
    def eat_food(name):
        print(f'{name},最爱吃饭,今年{Girl.age}岁')
        Girl.play_game()


girl = Girl(18)
girl.hello()
Girl.eat_food('小萝莉')

运行结果

一个实例方法,需要通过对象调用
my age is : 18
小萝莉,最爱吃饭,今年5岁
一个类方法,玩游戏

Process finished with exit code 0

关于实例方法、 classmethod 和 staticmethod 的实际应用场景

简单来说

  • 实例方法:方法内部需要访问实例属性、实例方法就定义为实例方法;既需要访问实例属性、方法,也需要访问类属性、方法,那必须定义为实例方法
  • 类方法:方法内部只需要访问类属性、类方法就定义为类方法
  • 静态方法:方法内部既不需要访问实例属性、实例方法,也不需要访问类属性、类方法就定义为静态方法

这玩意儿写完了,我还是有点晕 慢慢熟悉吧 。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/727676.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存