gpt4 book ai didi

python - 将 Python 方法动态绑定(bind)到实例会正确绑定(bind)方法名称,但不会绑定(bind)方法

转载 作者:太空宇宙 更新时间:2023-11-03 13:53:48 24 4
gpt4 key购买 nike

我正在为一组 RESTful 服务编写客户端。给定参数,REST 调用的主体具有相同的 XML 结构。有几十个调用,我不会实现所有的调用。因此,我想让它们易于指定和使用。 REST 方法按功能分组在单独的模块中,并且需要共享相同的 urllib2 opener 以进行身份​​验证和 cookie。下面是如何声明方法的示例:

@rest_method('POST', '/document')
def createDocument(id, title, body):
# possibly some validation on the arguments
pass

开发人员只需要关心验证即可。 XML(用于 POST 和 PUT)或 URL(用于 GET 和 DELETE)的格式以及响应的反序列化在辅助方法中完成。修饰的方法收集在一个客户端对象中,它们将从中执行和处理。例如:

c = RESTClient('http://foo.com', username, password)
c.createDocument(1, 'title', 'body')

代码完成。唯一的问题是将装饰方法附加到客户端类。尽管在客户端实例中可以看到所有被修饰的方法,但它们都具有相同的定义,即最后一个被绑定(bind)。这是一个重复我所看到的行为的简短示例:

import types

class C(object): pass
def one(a): return a
def two(a, b): return a+b
def bracketit(t): return '(%s)' % t

c = C()

for m in (one, two):
new_method = lambda self, *args, **kwargs:\
bracketit(m(*args, **kwargs))
method = types.MethodType(new_method, c, C)
setattr(C, m.__name__, method)

print c.one
print c.two
print c.two(1, 2)
print c.one(1)

当我运行它时,我得到以下输出:

<bound method C.<lambda> of <__main__.C object at 0x1003b0d90>>
<bound method C.<lambda> of <__main__.C object at 0x1003b0d90>>
(3)
Traceback (most recent call last):
File "/tmp/test.py", line 19, in <module>
print c.one(1)
File "/tmp/test.py", line 12, in <lambda>
bracketit(m(*args, **kwargs))
TypeError: two() takes exactly 2 arguments (1 given)

我不确定为什么这两种方法以相同的方式绑定(bind)。我没能找到很多关于 instancemethod 如何将方法绑定(bind)到实例的文档。引擎盖下发生了什么,我将如何修复上面的代码以便第二个调用打印“(1)”?

最佳答案

lambda 正在调用 m,将其从本地作用域中拉出。 for循环结束后,m被设置为two。调用 c.onec.two 将导致调用 two

您可以通过查看回溯的最后一行来判断正在调用 two:

TypeError: two() takes exactly 2 arguments (1 given)

A good demonstration of what is going on can be found here.

这应该符合您的预期,但是有点困惑:

class C(object): pass
def one(a): return a
def two(a, b): return a+b
def bracketit(t): return '(%s)' % t

c = C()

for m in (one, two):
def build_method(m):
return (lambda self, *args, **kwargs:
bracketit(m(*args, **kwargs)))
method = build_method(m)
setattr(C, m.__name__, method)

print c.one
print c.two
print c.two(1, 2)
print c.one(1)

我还删除了未绑定(bind)方法的显式创建,因为它是不必要的。

关于python - 将 Python 方法动态绑定(bind)到实例会正确绑定(bind)方法名称,但不会绑定(bind)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1810514/

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