全部放一个里面篇幅过大了,就拆分成1个个发布
示例代码
class Human:
def __init__(self, name):
self.name = name
def say(self):
print(f'我的名字是{self.name}')
@classmethod
def walk(self):
print('类方法 walk')
@staticmethod
def sleep():
print('类静态方法 sleep')
一般这样调用
# 类名.类方法
Human.walk()
# 实例名.实例方法
wuxianfeng = Human('wuxianfeng')
wuxianfeng.say()
# 静态方法则无所谓
Human.sleep()
wuxianfeng.sleep()
问题就是,实例能否调用类方法?类能否调用实例方法呢?
-
实例能否调用类方法:能,比如wuxianfeng.walk()
-
类能否调用实例方法:不能,比如Human.say()
TypeError: say() missing 1 required positional argument: 'self'
小结
方法 | 装饰器 | 参数 | 调用方 |
---|---|---|---|
类方法 | @classmethod | cls | 类,实例(不推荐) |
实例方法 | 无 | self | 实例 |
静态方法 | @staticmethod | 无默认参数 | 类(推荐),实例(不推荐) |
cls代指类本身,self代指实例
class Person:
@classmethod
def eat(cls): # 这里的cls就是指Person
pass
def drink(self): # 这里的self就是指Person()出来的实例
pass
cls和self这2个名字只是约定,见名知义,不建议更改,IDE会给你提示,其他地方需要自己注意,事实上你可以写成任意的名字,但不推荐
class Person:
@classmethod
def eat(class_name):
print('eat')
def drink(instance_name):
print('drink')
Person.eat() # 没毛病
Person().drink() # 没毛病
pycharm中的提示信息
官网
@classmethod
把一个方法封装成类方法。
一个类方法把类自己作为第一个实参,就像一个实例方法把实例自己作为第一个实参。请用以下习惯来声明类方法:
class C:
@classmethod
def f(cls, arg1, arg2): ...
@classmethod
这样的形式称为函数的 decorator
类方法的调用可以在类上进行 (例如 C.f()
) 也可以在实例上进行 (例如 C().f()
)。 其所属类以外的类实例会被忽略。 如果类方法在其所属类的派生类上调用,则该派生类对象会被作为隐含的第一个参数被传入。
类方法与 C++ 或 Java 中的静态方法不同。 如果你需要后者,请参阅本节中的 staticmethod()
。
@staticmethod
将方法转换为静态方法。
静态方法不会接收隐式的第一个参数。要声明一个静态方法,请使用此语法
class C:
@staticmethod
def f(arg1, arg2, ...): ...
@staticmethod
这样的形式称为函数的 decorator
静态方法的调用可以在类上进行 (例如 C.f()
) 也可以在实例上进行 (例如 C().f()
)。
Python中的静态方法与Java或C ++中的静态方法类似。另请参阅 classmethod()
,用于创建备用类构造函数的变体。
像所有装饰器一样,也可以像常规函数一样调用 staticmethod
,并对其结果执行某些操作。比如某些情况下需要从类主体引用函数并且您希望避免自动转换为实例方法。对于这些情况,请使用此语法:
class C:
builtin_open = staticmethod(open)