鱼C论坛

 找回密码
 立即注册
查看: 795|回复: 0

[学习笔记] 类和对象-类方法@classmethod

[复制链接]
发表于 2023-4-2 15:41:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
>>> #类方法和静态方法。类方法是指用于绑定类的方法,用@classmethod装饰器来定义,绑定的是类而非实例对象;静态方法则是指放在类中的函数,用@staticmethod装饰器来定义,无需绑定。使用类方法和静态方法都不必担心实例属性覆盖类属性的问题。实际中要根据应用场景“因地制宜”,当操作不涉及类属性或实例属性引用时使用静态方法,当统计实例对象数量时使用类方法更好,在涉及继承时可实现自动化,分别统计,易于扩展,简单便捷!
>>> #类方法:classmethod装饰器,绑定的是一个类而非对象
>>> class C:
...         def funA(self):
...                 print(self)
...         @classmethod
...         def funB(cls):
...                 print(cls)
...
>>> c = C()
>>> c.funA()
<__main__.C object at 0x00BAF430>
>>> c.funB()
<class '__main__.C'>

>>> #普通方法绑定的是一个对象object,类方法绑定的是类C
>>> #self和cls均为约定俗成的写法,更换了也没有错

>>> class C:
...         count = -0
...
>>> class C:
...         count = 0
...         def __init__(self):
...                 C.count += 1
...         @classmethod
...         def get_count(cls):
...                 print(f'该类一共实例化了{cls.count}个对象')
...
>>> c1 = C()
>>> c2 = C()
>>> c3 = C()
>>> c1.get_count()
该类一共实例化了3个对象
>>> #如果在一个对象中创建一个跟类属性同名的实例属性,则后者就会覆盖类属性,但这里由于get_count是类方法,所以就算实例属性覆盖了类属性,也不会改变类属性
>>> c3.count = 1
>>> print(c2.count)
3
>>> print(c3.count)
1
>>> c3.get_count()
该类一共实例化了3个对象
>>> print(C.count)
3

>>> # 虽然直接使用类名来访问类属性也可以,但如果涉及到继承问题,那么使用类方法会有更大的优势
>>> # 静态方法:staticmethod装饰器,放在类里边的函数。在类里边定义一个不需要绑定对象(self)的函数

>>> class C:
...         @staticmethod
...         def funC():
...                 print('i loe you')
...
>>> c = C()
>>> c.funC()
i loe you
>>> C.funC()
i loe you
>>> class C:
...         count = 0
...         def __init__(self):
...                 C.count += 1
...         @staticmethod
...         def get_count():
...                 print(f'该类一共实例化了{C.count}个对象')
...
>>> c1 = C()
>>> c2 = C()
>>> c3 = C()
>>> c1.get_count()
该类一共实例化了3个对象
>>> c3.count = 1
>>> print(c3.count)
1

>>> # 当操作不涉及类属性或实例属性引用时使用静态方法比较合适,如果像统计实例对象这种任务时,使用类方法实现更好
>>> class C:
...         count = 0
...         @classmethod
...         def add(cls):
...                 cls.count += 1
...         def __init__(self):
...                 self.add()
...         @classmethod
...         def get_count(cls):
...                 print(f'该类一共实例化了{cls.count}个对象')
...
>>> class D(C):
...         count = 0
...
>>> class E(C):
...         count = 0
...
>>> c1 = C()
>>> d1, d2 = D(), D()
>>> e1, e2, e3 = E(), E(), E()
>>> c1.get_count()
该类一共实例化了1个对象
>>> d1.get_count()
该类一共实例化了2个对象
>>> e1.get_count()
该类一共实例化了3个对象
>>> # 当代码涉及到继承的时候,实例对象的数量统计就变得复杂了,此时类方法的优势便体现出来了。独立出一个add()的类方法,这样做是为了实现自动化,让构造函数调用add()类方法,就不用管他是子类还是父类,谁去调用谁就会自动把对应的类传递进去,那么递增的也就是该类对应的count类属性,相当于各回各家各找各妈。我们要做的就是在继承的时候覆盖一下对应类的count属性,就可以轻松实现各个类实例的对象数量统计。
>>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-24 07:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表