![](/img/trans.png)
[英]Add a decorator to a class add a decorator to class' methods by decorating class
[英]Python dynamically add decorator to class' methods by decorating class
說我上課了:
class x:
def first_x_method(self):
print 'doing first_x_method stuff...'
def second_x_method(self):
print 'doing second_x_method stuff...'
和這個裝飾
class logger:
@staticmethod
def log(func):
def wrapped(*args, **kwargs):
try:
print "Entering: [%s] with parameters %s" % (func.__name__, args)
try:
return func(*args, **kwargs)
except Exception, e:
print 'Exception in %s : %s' % (func.__name__, e)
finally:
print "Exiting: [%s]" % func.__name__
return wrapped
我將如何編寫另一個裝飾器otherdecorator
以便:
@otherdecorator(logger.log)
class x:
def first_x_method(self):
print 'doing x_method stuff...'
def first_x_method(self):
print 'doing x_method stuff...'
同樣的
class x:
@logger.log
def first_x_method(self):
print 'doing first_x_method stuff...'
@logger.log
def second_x_method(self):
print 'doing second_x_method stuff...'
或實際上取代
@otherdecorator(logger.log)
class x:
同
@otherdecorator
class x:
其他裝飾者包含所有功能(我不是蟒蛇人,所以要溫柔)
除非有明確的理由將類用作裝飾器,否則我認為使用函數定義裝飾器通常更容易。
這是創建類裝飾器trace
的一種方法,它使用log
裝飾器來裝飾類的所有方法:
import inspect
def log(func):
def wrapped(*args, **kwargs):
try:
print("Entering: [%s] with parameters %s" % (func.__name__, args))
try:
return func(*args, **kwargs)
except Exception as e:
print('Exception in %s : %s' % (func.__name__, e))
finally:
print("Exiting: [%s]" % func.__name__)
return wrapped
def trace(cls):
# https://stackoverflow.com/a/17019983/190597 (jamylak)
for name, m in inspect.getmembers(cls, lambda x: inspect.isfunction(x) or inspect.ismethod(x)):
setattr(cls, name, log(m))
return cls
@trace
class X(object):
def first_x_method(self):
print('doing first_x_method stuff...')
def second_x_method(self):
print('doing second_x_method stuff...')
x = X()
x.first_x_method()
x.second_x_method()
收益率:
Entering: [first_x_method] with parameters (<__main__.X object at 0x7f19e6ae2e80>,)
doing first_x_method stuff...
Exiting: [first_x_method]
Entering: [second_x_method] with parameters (<__main__.X object at 0x7f19e6ae2e80>,)
doing second_x_method stuff...
Exiting: [second_x_method]
這是一個trace
裝飾器的一個版本,實現為一個類,允許其他用例要求:傳遞函數來裝飾裝飾類的所有成員函數。
import inspect
def log(func):
def wrapped(*args, **kwargs):
try:
print "Entering: [%s] with parameters %s" % (func.__name__, args)
try:
return func(*args, **kwargs)
except Exception, e:
print 'Exception in %s : %s' % (func.__name__, e)
finally:
print "Exiting: [%s]" % func.__name__
return wrapped
class trace(object):
def __init__(self, f):
self.f = f
def __call__(self, cls):
for name, m in inspect.getmembers(cls, inspect.ismethod):
setattr(cls, name, self.f(m))
return cls
@trace(log)
class X(object):
def first_x_method(self):
print 'doing first_x_method stuff...'
def second_x_method(self):
print 'doing second_x_method stuff...'
x = X()
x.first_x_method()
x.second_x_method()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.