gpt4 book ai didi

python - "Unwraping"并在元类中再次包装@staticmethod

转载 作者:太空宇宙 更新时间:2023-11-03 21:28:27 26 4
gpt4 key购买 nike

我想创建元类,它将用跟踪装饰器装饰每个函数。

所以我得到了这个:

from functools import wraps
from inspect import getfile

from arrow import now


def trace(f):
@wraps(f)
def wrapper(*args, **kwargs):
print(
'{timestamp} - {file} - {function} - CALL *{args} ** {kwargs}'.format(timestamp=now().isoformat(sep=' '),
file=getfile(f),
function=f.__name__, args=args[1:],
kwargs=kwargs))
result = f(*args, **kwargs)
print(
'{timestamp} - {file} - {function} - RESULT {result}'.format(timestamp=now().isoformat(sep=' '),
file=getfile(f),
function=f.__name__,
result=result))
return result

return wrapper


class TraceLogger(type):
def __new__(mcs, name, bases, dct):
for attr in dct:
value = dct[attr]
if callable(value):
dct[attr] = trace(value)
return super(TraceLogger, mcs).__new__(mcs, name, bases, dct)


class ExampleClass(object):
__metaclass__ = TraceLogger

def foo(self):
print('foo')

@staticmethod
def bar():
print('bar')

example = ExampleClass()
example.foo()
example.bar()

跟踪适用于任何非静态函数,因为静态方法不可调用。如何解开 staticmethod 然后将其包装在 new metclass 中两次,如下所示:

dct[attr] = staticmethod(trace(value))

最佳答案

您可以通过调用 __get__ 来解开 staticmethod 对象。

@staticmethod
def func(*args):
print('func called:', args)
return 42

print(func)
print(func.__get__(None, object))
print(func.__get__(None, object)(1, 2, 3))

它输出:

<staticmethod object at 0x7f8d42835ac0>
<function func at 0x7f8d429561f0>
func called: (1, 2, 3)
42

至于为什么会这样,你可能有兴趣了解描述符协议(protocol)是什么,我推荐this link .

关于python - "Unwraping"并在元类中再次包装@staticmethod,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53694087/

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