gpt4 book ai didi

类或函数的python装饰器

转载 作者:太空狗 更新时间:2023-10-30 00:51:41 28 4
gpt4 key购买 nike

只是征求一下下面的做法是否合理,或者有没有更好的做法。基本上我想要一个将应用于实现 __call__ 的函数或类的装饰器。

您可以只使用一个常规装饰器并显式装饰 __call__,但装饰器隐藏在类定义中并且不那么明显。也许我缺少更直接的解决方案。

import types
from functools import wraps

class dec:
""" Decorates either a class that implements __call__
or a function directly.
"""
def __init__(self, foo):
self._foo = foo

def __call__(self, target):
wraps_class = isinstance(target, types.ClassType)
if wraps_class:
fun = target.__call__
else:
fun = target

@wraps(fun)
def bar(*args, **kwds):
val = args[1] if wraps_class else args[0]
print self._foo, val
return fun(*args, **kwds)
if wraps_class:
target.__call__ = bar
return target
else:
return bar

@dec('A')
class a:
# you could decorate here, but it seems a bit hidden
def __call__(self, val):
print "passed to a:", val

@dec('B')
def b(val):
print "passed to b:", val

a()(11)
b(22)

最佳答案

就我个人而言,我会把它分成两个装饰器:一个总是包装一个函数:

def func_dec(foo, is_method=False):
def wrapper(fun):
@wraps(fun)
def bar(*args, **kwds):
val = args[1] if is_method else args[0]
print foo, val
return fun(*args, **kwds)
return bar
return wrapper

另一个检测它是否应该修改 __call__ 方法或简单地包装一个函数:

def dec(foo):
def wrapper(obj):
if inspect.isclass(obj):
obj.__call__ = func_dec(foo, is_method=True)(obj.__call__)
return obj
else:
return func_dec(foo)(obj)
return wrapper

请注意,inspect.isclass 将在旧式和新式类中正确运行。

关于类或函数的python装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9295398/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com