2

Twython 模块在内部使用 requests 模块。

我想包装/装饰请求的requests.post(*k, **kw)方法,以便 Twythonrequest.post(...)调用的所有内容都将被透明地装饰/包装,而不会干扰 Twython 模块。

如果我编辑了请求代码库,那将很容易,但我很好奇如何解决将装饰器添加到已定义的函数/方法的一般问题。

import requests
def magic_wrapper_doodad(...)
...
...
requests.post = magic_wrapper_doodad(my_function, requests.post) # plz?

import Twython

# thanks to the above magic, requests.post is wrapped just as if it was defined like:
@decorator
def trace(f, *args, **kw):
    print("calling %s with args %s, %s" % (f.__name__, args, kw))
    return f(*args, **kw)

...
... #inside requests.py now:
@trace
def post(self, *args, **kw):
...

我该如何编写magic_wrapper_doodad()- 或一些替代代码 - 所以我可以像这样装饰代码?

4

3 回答 3

5

装饰器@符号只是用于调用装饰器可调用装饰器并用结果替换装饰器的语法糖。

换句话说,以下两个示例是完全相同的:

@yourdecorator
def a_function():
    pass

def b_function():
    pass
b_function = yourdecorator(b_function)

这同样适用于类定义中的方法。

因此,您可以通过将类方法替换为可调用装饰器的结果来简单地装饰类方法:

requests.post = my_function(requests.post)

这就像你写的一样:

class requests(object):
    @my_function
    def post(self, *args):
        pass

请注意,在您的情况下requests实际上是一个模块,而不是一个类,但同样的原则适用。

于 2012-08-03T21:51:20.440 回答
2

如果您需要装饰 requests 功能,Martijn Pieters 的回答是您的最佳选择。我只是想我会提到 requests 实际上有一种 hooks 机制

如果你可以用钩子做你需要做的事情,你应该这样做。它比猴子补丁更干净。

于 2012-08-03T22:00:31.787 回答
1

您正在寻找的内容可能通过面向方面的编程来完成。

查看 Stackoverflow 上的这篇文章,如果有帮助,请告诉我:

您在生产软件中使用 AOP(面向方面​​编程)吗?

于 2012-08-03T21:53:04.623 回答