Python中@staticmethod和@classmethod的用法

Python中@staticmethod和@classmethod的用法

一般来说,调用某个类的方法,需要预先生成一个实例,再通过实例调用方法。Java中有静态方法,可以使用类直接进行调用。Python中提供了两个修饰符@staticmethod@classmethod以达到类似效果,使用它们就可以不需要实例化,直接类名.方法名()来调用。这有利于组织代码,把某些应该属于某个类的函数给放到那个类中,同时有利于命名空间的整洁。

@staticmethod

@staticmethod声明方法为静态方法,直接通过类名.方法名()调用。经过@staticmethod修饰的方法,不需要self参数,其使用方法和直接调用函数一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#直接定义一个test()函数
def test():
print "i am a normal method!"

#定义一个类,其中包括一个类方法,采用@staticmethod修饰
class T:
@staticmethod
def static_test(): # 没有self参数
print "i am a static method!"


if __name__ == "__main__":
test()
T.static_test()
T().static_test()

output:
i am a normal method!
i am a static method!
i am a static method!

@classmethod

@classmethod声明方法为类方法,直接通过类名.方法名()调用。经过@classmethod修饰的方法,不需要self参数,但是需要一个标识类本身的cls参数

1
2
3
4
5
6
7
8
9
10
11
12
13
class T:
@classmethod
def class_test(cls): # 必须有cls参数
print "i am a class method"


if __name__ == "__main__":
T.class_test()
T().class_test()

output:
i am a class method
i am a class method

@classmethod另一个实用的用法:在不改变已经写好的类里面的方法的情况下,对输入的数据进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 输出年月日,正常的情况下
class demo1:
def __init__(self, year=0, month=0, day=0):
self.year = year
self.month = month
self.day = day

def out_date(self):
return "year: %d, month: %d, day: %d" % (self.year, self.month, self.day)

year = 2018
month = 10
day = 27

demo1 = demo1(year, month, day)
print(demo1.out_date()) # year: 2018, month: 10, day: 27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 如果用户输入的是2018-10-27格式,需要在输出前处理一下,就可以使用classmethod达到想要的效果
class demo2:
def __init__(self, year=0, month=0, day=0):
self.year = year
self.month = month
self.day = day

def out_date(self):
return "year: %d, month: %d, day: %d" % (self.year, self.month, self.day)

@classmethod
def pre_out(cls, date_string):
year, month, day = map(int, date_string.split("-"))
return cls(year, month, day)

date = "2018-10-27"
year = 2017
month = 7
day = 7

try:
demo2 = demo2.pre_out(date)
except:
demo2 = demo2(year, month, day)

print(demo2.out_date()) # year: 2018, month: 10, day: 6

小结

  • @staticmethod不需要表示自身对象的self参数和自身类的cls参数,就跟使用函数一样。
  • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。
  • 在Python中类和实例都是对象,都占用了内存空间,合理使用@staticmethod@classmethod修饰符,就可以不经过实例化直接使用类的方法了。

引用文章:

  1. Python @staticmethod@classmethod用法 - sinat_34079973的博客 - CSDN博客
  2. 飘逸的python - @staticmethod和@classmethod的作用与区别 - mattkang - CSDN博客
  3. classmethod的两个实用用法 - 简书