类方法 静态方法和实例方法¶
参考:
关键词:对象 绑定
Python 类中的方法大致可以分为三种:
- 类方法
- 实例方法
- 静态方法
class Foo(object):
def test1(self):
'''
定义了实例方法
'''
print('instance {}'.format(self))
@classmethod
def test2(cls):
'''
定义了类方法
'''
print('class {}'.format(cls))
@staticmethod
def test3(n):
'''
定义了静态方法
'''
print('static n = {}'.format(n))
访问方式¶
- 实例方法:通过实例和类进行访问,通过类访问需要手动绑定实例
s = Foo()
s.test1()
Foo.test1(s)
instance <__main__.Foo object at 0x00000236651661D0>
instance <__main__.Foo object at 0x00000236651661D0>
- 类方法:通过类或者实例进行访问
因为通过实例可以反推得到类,所以可以进行访问
s = Foo()
Foo.test2()
s.test2()
class <class '__main__.Foo'>
class <class '__main__.Foo'>
- 静态方法:通过类或者实例进行访问
s = Foo()
Foo.test3(5)
s.test3(5)
static n = 5
static n = 5
特性¶
- 实例方法 需要绑定实例才能运行
>>> Foo.test1
<function __main__.Foo.test1>
>>> s = Foo()
>>> s.test1
<bound method Foo.test1 of <__main__.Foo object at 0x00000236651379B0>>
如果未绑定的方法 Foo.test1 不传实例对象给 self 时,就会报参数缺失错误,python2 要求第一个参数self是实例对象,而 python3 中可以是任意对象。
- 类方法 无论通过类还是实例进行访问,都会自动绑定类
- 静态方法 类里面的一个普通函数,与类和实例都没有绑定关系,只是存在于类中为类服务,静态方法如果作为全局函数也不会有什么问题。
典型应用场景¶
- 类方法 作为工厂方法创建实例对象,例如内置模块 datetime.date 类中就有大量使用类方法作为工厂方法,以此来创建 date 对象。
class date:
def __new__(cls, year, month=None, day=None):
self = object.__new__(cls)
self._year = year
self._month = month
self._day = day
return self
@classmethod
def fromtimestamp(cls, t):
y, m, d, * = _time.localtime(t)
return cls(y, m, d)
@classmethod
def today(cls):
t = _time.time()
return cls.fromtimestamp(t)
如果需要在类中调用静态方法,最好把方法定义成类方法,因为要是定义成静态方法,那么就要显示地引用类 Foo,这对继承来说不是一件好事。
class Foo:
@staticmethod
def m1():
pass
@staticmethod
def m2():
A.m1() # bad
@classmethod
def m3(cls):
cls.m1() # good
- 静态方法 如果在方法中不需要访问任何实例方法和属性,纯粹地通过传入参数并返回数据,那么适合用静态方法,可以节省实例化对象的开销,通常这种方法放在类外面的模块层作为一个函数存在也是没问题的,而放在类中,仅为这个类服务。