class 方法和函数的装饰器
Decorator for both class methods and functions
我有装饰器
def deco(func):
def inner(params):
#< DO STUFF WITH func >
return inner
还有一个基地class
class GenericClass:
def __init__(self,value):
self.value = value
def method(self,params):
print 'NOT IMPLEMENTED YET'
def other_method(self):
print 'GOOD TO GO'
我希望能够在 classes 上装饰 "method" 方法,它是 GenericClass 的子类,例如检查 input/output 或处理异常(方法 "method" 将被覆盖)
我想做的是...
class ChildClass(GenericClass):
@deco
def method(self,params):
#< NEW METHOD >
我不是专家 python 开发人员并且该级别的所有文档都非常混乱(即元 classes、装饰器的微妙之处、__call__
方法等)和我没有在 SO 上找到解决方案。
知道了。您基本上是在询问如何编写可应用于函数和方法的装饰器。有可能:
def deco(func):
def inner(*args):
print('DECORATED: args={}'.format(args))
func(*args)
return inner
class Class:
@deco
def method(self, param): print('PARAM is {}'.format(param))
@deco
def func(a, b, c): print('{} {} {}'.format(a, b, c))
Class().method('X')
func(1, 2, 3)
输出:
DECORATED: args=(<__main__.Class instance at 0x7f740c6297a0>, 'X')
PARAM is X
DECORATED: args=(1, 2, 3)
1 2 3
P.S.
一年后,我在这里找到了一个有用的post(8 年前有人问过):Using the same decorator (with arguments) with functions and methods。如果您关心装饰函数的实际参数,那里描述的方法将很有用。
我明白了。诀窍是 module-level 函数(我猜除了闭包,你可能不想修饰它)有一个简单的名字,而方法的限定名至少有两个部分。
忘记 inspect.ismethod - 由于某种原因,它在这种情况下不起作用,尽管它应该是显而易见的选择,可能是一个错误。
def can(*fargs):
def wrapper(func):
if len(func.__qualname__.split('.')) > 1:
def calling(self, *args, **kwargs):
self, thing = args[0], args[1]
do_stuff(thing)
func(*args, **kwargs)
else:
def calling(*args, **kwargs):
thing = args[0]
do_stuff(thing)
func(*args, **kwargs)
return calling
return wrapper
class C:
@can(2, 3)
def test(self, x):
print(7, ismethod(self.test), x)
@can()
def test(x):
print(8, ismethod(test), x)
c = C()
c.test(12)
test(8)
我有装饰器
def deco(func):
def inner(params):
#< DO STUFF WITH func >
return inner
还有一个基地class
class GenericClass:
def __init__(self,value):
self.value = value
def method(self,params):
print 'NOT IMPLEMENTED YET'
def other_method(self):
print 'GOOD TO GO'
我希望能够在 classes 上装饰 "method" 方法,它是 GenericClass 的子类,例如检查 input/output 或处理异常(方法 "method" 将被覆盖)
我想做的是...
class ChildClass(GenericClass):
@deco
def method(self,params):
#< NEW METHOD >
我不是专家 python 开发人员并且该级别的所有文档都非常混乱(即元 classes、装饰器的微妙之处、__call__
方法等)和我没有在 SO 上找到解决方案。
知道了。您基本上是在询问如何编写可应用于函数和方法的装饰器。有可能:
def deco(func):
def inner(*args):
print('DECORATED: args={}'.format(args))
func(*args)
return inner
class Class:
@deco
def method(self, param): print('PARAM is {}'.format(param))
@deco
def func(a, b, c): print('{} {} {}'.format(a, b, c))
Class().method('X')
func(1, 2, 3)
输出:
DECORATED: args=(<__main__.Class instance at 0x7f740c6297a0>, 'X')
PARAM is X
DECORATED: args=(1, 2, 3)
1 2 3
P.S.
一年后,我在这里找到了一个有用的post(8 年前有人问过):Using the same decorator (with arguments) with functions and methods。如果您关心装饰函数的实际参数,那里描述的方法将很有用。
我明白了。诀窍是 module-level 函数(我猜除了闭包,你可能不想修饰它)有一个简单的名字,而方法的限定名至少有两个部分。 忘记 inspect.ismethod - 由于某种原因,它在这种情况下不起作用,尽管它应该是显而易见的选择,可能是一个错误。
def can(*fargs):
def wrapper(func):
if len(func.__qualname__.split('.')) > 1:
def calling(self, *args, **kwargs):
self, thing = args[0], args[1]
do_stuff(thing)
func(*args, **kwargs)
else:
def calling(*args, **kwargs):
thing = args[0]
do_stuff(thing)
func(*args, **kwargs)
return calling
return wrapper
class C:
@can(2, 3)
def test(self, x):
print(7, ismethod(self.test), x)
@can()
def test(x):
print(8, ismethod(test), x)
c = C()
c.test(12)
test(8)