gpt4 book ai didi

python - 如何包装(猴子补丁)@classmethod

转载 作者:太空狗 更新时间:2023-10-30 02:11:48 25 4
gpt4 key购买 nike

我想猴子修补一个类方法,保留旧功能。考虑我的代码来理解这个想法。这是我的代码(非常综合的例子)。

#!/usr/bin/env python

class A:

@classmethod
def foo(kls, param):
print 'A.foo called, param is ' + param

def bar(self, param):
print 'A.bar called, param is ' + param


a = A()
a.foo('param_foo')
a.bar('param_bar')

# Patching things

def bar_wrapper(wrapped_func):
def _w(*args, **kwargs):
print '<bar_wrap>'
wrapped_func(*args, **kwargs)
print '</bar_wrap>'
return _w

def foo_wrapper(wrapped_func):
# Something missing here?
def _w(*args, **kwargs):
print '<foo_wrap>'
wrapped_func(*args, **kwargs)
print '</foo_wrap>'
return _w

# Everything is pretty ok
A.bar = bar_wrapper(A.bar)
a.bar('is_is_wrapped?')

# Failed to wrap @classmethod
A.foo = foo_wrapper(A.foo)
A.foo('another_wrap_test')

这是我期望的输出:

A.foo called, param is param_foo
A.bar called, param is param_bar
<bar_wrap>
A.bar called, param is is_is_wrapped?
</bar_wrap>
<foo_wrap>
A.foo called, param is another_wrap_test
</foo_wrap>

这就是我得到的:

A.foo called, param is param_foo
A.bar called, param is param_bar
<bar_wrap>
A.bar called, param is is_is_wrapped?
</bar_wrap>
Traceback (most recent call last):
File "./pytest.py", line 39, in <module>
A.foo('another_wrap_test')
TypeError: unbound method _w() must be called with A instance as first argument (got str instance instead)

似乎有一个参数(类参数)在包装过程中丢失了。或者我只是没有装饰功能的想法?

提前致谢。

最佳答案

当您访问一个类的方法时,它在那一刻被包装;方法充当 descriptors在这里。

您可能想再次解包该方法,返回一个包装好的包装器:

def foo_wrapper(wrapped_func):
wrapped_func = wrapped_func.__func__
def _w(*args, **kwargs):
print '<foo_wrap>'
wrapped_func(*args, **kwargs)
print '</foo_wrap>'
return classmethod(_w)

现在返回的装饰器本身就是一个类方法,包装有效:

>>> class A:
... @classmethod
... def foo(kls, param):
... print 'A.foo called, param is ' + param
...
>>> def foo_wrapper(wrapped_func):
... wrapped_func = wrapped_func.__func__
... def _w(*args, **kwargs):
... print '<foo_wrap>'
... wrapped_func(*args, **kwargs)
... print '</foo_wrap>'
... return classmethod(_w)
...
>>> A.foo = foo_wrapper(A.foo)
>>> A.foo('bar')
<foo_wrap>
A.foo called, param is bar
</foo_wrap>

关于python - 如何包装(猴子补丁)@classmethod,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20121390/

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