官方解释
- @classmethod
一个类方法把类自己作为第一个实参, 就像一个实例方法把实例自己作为第一个实参.
语法格式:
class C:
@classmethod
def f(cls, arg1, arg2, ...): ...
- @staticmethod
静态方法不会接收隐式的第一个参数.
语法格式:
class C:
@staticmethod
def f(arg1, arg2, ...): ...
特性
相同点
- 可不实例化类直接调用
import time
class School(object):
school_name = "A_Tester_School"
address = "China_Sichuan"
def __init__(self, student_name):
self.student_name = "a student of A_Tester_School, name is: {} ".format(student_name)
def age(self, birthday):
return time.localtime().tm_year - birthday
@classmethod
def get_school(cls):
return cls.school_name, cls.address
@staticmethod
def get_address():
return "hello world."
# 实例调用
my_school = School("Hoo")
print(my_school.age(1991))
print(my_school.get_school())
print(my_school.get_address())
print("-"*50)
# 不实例化调用
print(School.get_school())
print(School.get_address())
# 28
# ('A_Tester_School', 'China_Sichuan')
# hello world.
# --------------------------------------------------
# ('A_Tester_School', 'China_Sichuan')
# hello world.
不同点
语法格式 | 至少一个参数,第一个参数为类本身 | 可无参数 |
个人理解
- 二者区别
- staticmethod装饰的函数就是一个普通的函数, 本质上与类没有半毛钱关系.所以无法使用类的局部变量(如:School类中的school_name), 无法操作类等.
- classmethod装饰的函数第一个入参为类本身, 因此可操作类, 包括引用类的staticmethod装饰的函数.
class ChildSchool(School):
@classmethod
def get_student_info(cls, student_name, birthday):
my_school = cls(student_name) # 实例化类
age1 = my_school.age(birthday) # 调用实例方法
print("school_name: {}".format(cls.school_name)) # 不实例类, 调用类局部变量
print("address: {}".format(my_school.address)) # 实例类, 调用类局部变量. 此处my_school可换成cls
print("age: {}".format(age1))
print("introduction: {}".format(my_school.student_introduction)) # 调用实例属性
print("this a error address: {}".format(cls.get_address())) # 调用类静态方法
ChildSchool.get_student_info("Hoo", 1991)
# school_name: A_Tester_School
# address: China_Sichuan
# age: 28
# introduction: a student of A_Tester_School, name is: Hoo
# this a error address: hello world.