Python中的普通方法、静态方法和类方法

普通方法(实例方法)

类中最常用的方法是实例方法, 即通过通过实例作为第一个参数的方法。

1
2
3
4
5
6
7
8
9
class A(object):
def __init__(self, data):
self.data = data
def printA(self):
print(self.data)
a1 = A('arun')
a2 = A('seema')
a1.printA()
a2.printA()

类方法(@classmethod)

仅仅与类交互而不是和实例交互的方法。

1
2
3
4
5
6
7
8
9
10
11
class A(object):
no_inst = 0
def __init__(self):
A.no_inst = A.no_inst + 1
@classmethod
def get_no_of_instance(cls_obj):
return cls_obj.no_inst
a1 = A()
a2 = A()
print a1.get_no_of_instance()
print A.get_no_of_instance()

好处是: 不管这个方式是从实例调用还是从类调用,它都用第一个参数把类传递过来。

静态方法(@staticmethod)

经常有一些跟类有关系的功能但在运行时又不需要实例和类参与的情况下需要用到静态方法。比如更改环境变量或者修改其他类的属性等能用到静态方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
IND = 'ON'
class A(object):
def __init__(self, data):
self.data = data
@staticmethod
def check():
return (IND == 'ON')
def do(self):
if self.check():
print('do for:', self.data)
def set(self):
if self.check():
self.db = 'New db connection'
print('DB connection made for: ', self.data)
a1 = A(12)
a1.do()
a1.set()
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
class A(object):
def __init__(self, data):
self.data = data
def printd(self):
print(self.data)
@staticmethod
def smethod(*arg):
print('Static:', arg)
@classmethod
def cmethod(*arg):
print('Class:', arg)

>>> a = A(23)
>>> a.printd()
23
>>> a.smethod()
Static: ()
>>> a.cmethod()
Class: (<class '__main__.A'>,)
>>> A.printd()
TypeError: unbound method printd() must be called with A instance as first argument (got nothing instead)
>>> A.smethod()
Static: ()
>>> A.cmethod()
Class: (<class '__main__.A'>,)
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
>>> class A(object):
def __init__(self, data):
self.data = data
def printd(self):
return self.data
@staticmethod
def smethod(*arg):
print('Static:', arg)
@classmethod
def cmethod(*arg):
print('Class:', arg)


>>> a1 = A()
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
a1 = A()
TypeError: __init__() missing 1 required positional argument: 'data'
>>> a1 = A(23)
>>> a1.printd()
23
>>> a1.smethod()
Static: ()
>>> a1.cmethod()
Class: (<class '__main__.A'>,)
>>> a1.smethod(11)
Static: (11,)
>>>
>>> a1.smethod(11, 12, 13)
Static: (11, 12, 13)
>>> a1.cmethod(11)
Class: (<class '__main__.A'>, 11)
>>> a1.cmethod(11, 13, 12)
Class: (<class '__main__.A'>, 11, 13, 12)
>>> A.cmethod(11, 12)
Class: (<class '__main__.A'>, 11, 12)
>>> A.printd()
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
A.printd()
TypeError: printd() missing 1 required positional argument: 'self'
  • @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
  • @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。

如果在@staticmethod中要调用到这个类的一些属性方法,只能直接类名.属性名或类名.方法名。

@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。

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
class A(object):  
b = 1
def fn(self):
print('fn')

@staticmethod
def static_fn():
print('static_fn')
print(A.b)

@classmethod
def class_fn(cls):
print('class_fn')
print(cls.b)
cls().fn()

A.static_fn()
A.class_fn()

static_fn
1

class_fn
1
fn