[英]How to create class class object and function class object in python
[英]How to get class function object in Python class?
我想在調用 function 之前做一些准備操作(例如日志記錄)。
例如,
class Test(object):
def float(self, target):
logging.info('Call float() function')
return float(target)
def int(self, target):
logging.info('Call int() function')
return int(target)
t = Test()
a = t.float('123')
b = t.int('123')
但是,現在我有大約 20 個函數需要做同樣的事情。 有什么辦法可以使用 1 function 來適應所有這些嗎? 就像是,
class Test(object):
def __getattr__(self, name):
def wrapper(args):
return func(args) # is there any built-in funciton can get function object?
logging.info('Call %s() function' % name)
return wrapper
您可以使用裝飾器,在繼續調用method
之前打印出方法的名稱:
def namer(var):
def wrapper(*args, **kwargs):
print(f'Call {var.__name__}() method')
return var(*args, **kwargs)
return wrapper
class Test(object):
@namer
def float(self, target):
return float(target)
@namer
def int(self, target):
return int(target)
t = Test()
a = t.float('123')
b = t.int('123')
print(a, b)
Output:
Call float() method
Call int() method
123.0 123
這就是您想要的(並且您不需要為每個函數添加decorator
):
class Test(object):
def float(self, target):
return float(target)
def int(self, target):
return int(target)
def __getattribute__(self, name):
attr = super().__getattribute__(name)
print(f'Call {attr.__name__}() method')
return attr
t = Test()
a = t.float('123')
b = t.int('123')
print(a, b)
Output:
Call float() method
Call int() method
123.0 123
這將包括在方法的日志記錄中使用的 arguments。
from functools import wraps
def logit(function):
@wraps(function)
def traced_func(self, *args, **kwargs):
sargs = list(args)
sargs += ["{farg}={fval!r}".format(farg=farg, fval=fval) for farg, fval in kwargs.items()]
print('Call {}({})'.format(function.__name__, ", ".join(map(str,sargs))))
rt = function(self, *args, **kwargs)
return rt
return traced_func
class Something(object):
@logit
def float(self, target, arg=None):
return float(target)
@logit
def int(self, target):
return int(target)
t = Something()
x = t.float(4, arg=9)
z = t.float(5)
y = t.int(8)
output
Call float(4, arg=9)
Call float(5)
Call int(8)
一般來說,我會建議將裝飾器放在每個方法之上,這樣更謹慎和可讀。 但是,您確實問過是否有辦法避免這樣做......
在 class 上使用裝飾器的裝飾器。
# use the same decorator as the above example along with this
def decorate_methods(decorator):
def traced_func(cls):
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
setattr(cls, attr, decorator(getattr(cls, attr)))
return cls
return traced_func
@decorate_methods(logit)
class Test(object):
def float(self, target):
return float(target)
def int(self, target):
return int(target)
你可以做func = eval(name)
。 它不是很優雅,也不是很安全,但可以完成您想要的工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.