@staticmethod@classmethod
https://zhuanlan.zhihu.com/p/28010894
Python面向对象编程中,类中定义的方法可以是
@classmethod 装饰的类方法,
也可以是 @staticmethod 装饰的静态方法,
用的最多的还是不带装饰器的实例方法。
class A(object):
def m1(self, n):
print("self:", self)
@classmethod
def m2(cls, n):
print("cls:", cls)
@staticmethod
def m3(n):
pass
a = A()
a.m1(1) # self: <__main__.A object at 0x000001E596E41A90>
A.m2(1) # cls: <class '__main__.A'>
A.m3(1)
我在类中一共定义了3个方法,
m1 是实例方法,第一个参数必须是 self(约定俗成的)。
m2 是类方法,第一个参数必须是cls(同样是约定俗成)。
m3 是静态方法,参数根据业务需求定,可有可无。
当程序运行时,大概发生了这么几件事(结合下面的图来看)。
- 第一步:代码从第一行开始执行 class 命令,此时会创建一个类 A 对象(没错,类也是对象,一切皆对象嘛)同时初始化类里面的属性和方法,记住,此刻实例对象还没创建出来。
- 第二、三步:接着执行 a=A(),系统自动调用类的构造器,构造出实例对象 a
- 第四步:接着调用 a.m1(1) ,m1 是实例方法,内部会自动把实例对象传递给 self 参数进行绑定,也就是说, self 和 a 指向的都是同一个实例对象。
- 第五步:调用A.m2(1)时,python内部隐式地把类对象传递给 cls 参数,cls 和 A 都指向类对象。
严格意义上来说,左边的都是变量名,是对象的引用,右边才是真正的对像,为了描述方便,我直接把 a 称为对象,你应该明白我说对象其实是它所引用右边的那个真正的对象。
@classmethod example
classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。
class A(object):
bar = 1
def func1(self):
print('foo')
@classmethod
def func2(cls):
print('func2')
print(cls.bar)
cls().func1() # 调用 foo 方法
A.func2() # 不需要实例化
##############################
func2
1
foo
@函数装饰器
https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2015-3-25')
now()
把@log
放到now()
函数的定义处,相当于执行了语句:
now = log(now)
example 2:
#funA 作为装饰器函数
def funA(fn):
print("C语言中文网")
fn() # 执行传入的fn参数
print("http://c.biancheng.net")
return "装饰器函数的返回值"
@funA
def funB():
print("学习 Python")
print(funB)
############
C语言中文网
学习 Python
http://c.biancheng.net
装饰器函数的返回值