@staticmethod
该装饰器可以讲类中的方法转为静态方法,以people类为例
为什么要有@staticmethod装饰器
class people:
def eat(self):
print("我要开始吃东西了~")
在正常情况下,如果我们想要使用eat方法,必须先实例化这个类。例如这样
P = people()
P.eat()
但是有些时候,我们并不像实例化这个类,因为用不到这个类,仅仅想要用到这个方法,为了一口醋而包一顿饺子明显是不好的,但是如果我们正常编写类的情况下,你会发现不进行实例化,直接调用,会出现如下结果:
class people:
def eat(self):
print("我要开始吃东西了~")
people.eat()
# output: TypeError: people.eat() missing 1 required positional argument: 'self'
那么如果我们想不进行实例化就调用这个函数呢?这个时候就要用到@staticmethod这个python自带的装饰器了。
@staticmethod装饰器的使用
将eat方法添加@staticmethod装饰器
class people:
@staticmethod
def eat():
print("我要开始吃东西了~")
people.eat()
# output: 我要开始吃东西了~
可以看到,程序正常运行了,所以在这里就可以看出来,@staticmethod的核心作用就是可以实现不创造一个新对象的情况下调用这个方法。
基本上到这里就已经明确了staticmethod的核心作用了,但是还有一些小的细节,可能让我们在后面使用时会产生一些理解不清楚,在这里也做一个简要的批注
staticmethod装饰的方法子类能否使用?
答案是:如果子类没有,会自动调用父类,子类存在,则以子类为准
class people:
@staticmethod
def eat():
print("人要吃东西")
@staticmethod
def run():
print("人在奔跑")
@staticmethod
def work():
print("人在工作")
class Student(people):
@staticmethod
def run():
print("学生在奔跑")
def work(self):
print("学生在学习")
if __name__ == "__main__":
# 检查子类还能否正常调用父类的方法
Student.eat()
# 检查当子类和父类都存在的情况下,用的是谁的
Student.run()
# 检查当子类没有静态装饰,父类静态装饰,能否不报错
Student.work()
打印结果如下:
TypeError: Student.work() missing 1 required positional argument: 'self'
人要吃东西
学生在奔跑
弊端1: 无法使用self
首先,使用staticmethod装饰的函数,是不需要self参数的,因为它是独立与类之外的(不用实例化就可以使用,self只有在实例化之后才能存在,而且默认作为类方法的第一个参数),staticmethod可以有参数,但是不会再存在实例化之后,第一个参数表示的类本身,这也就导致了,无法调用对象的内容。
class people:
def __init__(self):
self.name = "张三"
self.age = 18
@staticmethod
def eat(self):
"""这里的self只是一个参数名称"""
print(f"{self.name}在吃饭")
def run(a):
"""self不是固定的参数名称,只是一种书写规范,类方法的第一个参数代表类本身,可以是任何名称"""
print(f"{a.name}在奔跑")
# people.eat(18) # 这里会报错
P = people()
P.run()
弊端2: 不使用staticmethod装饰也不是不能实现静态方法
class people:
def __init__(self):
self.name = "张三"
self.age = 18
def eat(self):
print(f"{self}在吃饭")
people.eat("张三")
最开始我以为这种方法会报错,但是实际测试后发现,竟然可以正常运行?可能这也跟Python是一个动态语言,不限制参数类型有关系吧。