在以下情况中,使用以下命令setattr
在第一次调用中成功,但是在第二次调用中失败:
AttributeError: 'method' object has no attribute 'i'
为什么会这样,并且有一种方法可以在方法上设置属性,使其仅存在于一个实例上,而不是针对类的每个实例?
class c:
def m(self):
print(type(c.m))
setattr(c.m, 'i', 0)
print(type(self.m))
setattr(self.m, 'i', 0)
Python 3.2.2
简短的答案:无法将自定义属性添加到绑定方法。
长答案如下。
在Python中,有 函数对象 和 方法对象 。当定义一个类时,该def
语句创建一个 函数对象 ,该 对象 位于该类的名称空间中:
>>> class c:
... def m(self):
... pass
...
>>> c.m
<function m at 0x025FAE88>
函数对象具有特殊的__dict__
属性,可以保存用户定义的属性:
>>> c.m.i = 0
>>> c.m.__dict__
{'i': 0}
方法对象是不同的野兽。它们是微小的对象,仅持有对相应功能对象(__func__
)的引用,并对其宿主对象(__self__
)的引用:
>>> c().m
<bound method c.m of <__main__.c object at 0x025206D0>>
>>> c().m.__self__
<__main__.c object at 0x02625070>
>>> c().m.__func__
<function m at 0x025FAE88>
>>> c().m.__func__ is c.m
True
方法对象提供了一种特殊__getattr__
的功能,可将属性访问转发给功能对象:
>>> c().m.i
0
对于该__dict__
属性也是如此:
>>> c().m.__dict__['a'] = 42
>>> c.m.a
42
>>> c().m.__dict__ is c.m.__dict__
True
但是,设置属性遵循默认规则,并且由于它们没有自己的__dict__
属性,因此无法设置任意属性。
这类似于定义__slots__
且没有__dict__
插槽的用户定义类,当尝试设置一个不存在的插槽时会引发一个AttributeError
(请参阅文档,__slots__
以获取更多信息):
>>> class c:
... __slots__ = ('a', 'b')
...
>>> x = c()
>>> x.a = 1
>>> x.b = 2
>>> x.c = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'c' object has no attribute 'c'
问题内容: 我有一个项目,我试图在回调中使用weakrefs,但我不明白我在做什么错。我创建了简化的测试,以显示我困惑的确切行为。 为什么在此测试中test_a可以正常工作,但是self.MyCallbackB的weakref在类初始化和调用test_b之间消失了?我以为只要实例(a)存在,对self.MyCallbackB的引用就应该存在,但是不存在。 问题答案: 您需要一个WeakMethod
问题内容: 我之所以问这个问题,是因为对该答案的评论主题进行了讨论。我有90%的方法可以解决问题。 存在三种不同形式: 绑定方法 , 未绑定方法 和 函数 对象之间的区别是什么,所有这些都由f1描述?一个人怎么称呼这三个物体?它们如何相互转化?关于这些东西的文档很难理解。 问题答案: 一个 功能 是创建由声明,或通过。在Python 2下,当函数出现在语句主体中(或传递给类构造调用)时,它将转换为
setAttr(String, Object) 转调了 HttpServletRequest.setAttribute(String, Object),该方法可以将各种数据传递给View并在View中显示出来。 通过查看 jfinal 源码 Controller 可知 setAttr(String, Object) 方法在底层仅仅转调了底层的 HttpServletRequest 方法: priv
请巨佬们给我看一个问题第一次写小程序,进入页面调了一个getUserInfo获取信息接口然后框里的数据全部正确显示出来了,但是我编辑完表单之后formData里还是没有变请问有啥问题吗
问题内容: 当我实现接口方法时,Eclipse将添加@Override批注。Eclipse似乎对此没有任何问题。而且,来自Cruise Control的自动化构建过程似乎对此没有问题。但是,当我从命令行构建并运行Javac的ant时,出现以下错误: Eclipse在Java 1.6下运行。Cruise Control正在运行Java 1.5。无论我使用哪个Java版本,我的蚂蚁构建都会失败。 问题
这应该很简单,但我在这里错过了一些东西。我有两个玩具类:(a)一个需要连接并提供文件的服务器;和 (b) 请求文件并将其打印在标准输出上的客户端。 服务器代码: 客户代码: 我试图在同一台机器上同时运行服务器和客户机,但是每次我试图运行客户机时,总是从服务器得到这条消息: !!!ERRO:地址已在使用中(绑定失败) 要运行这段代码而不出错,我还需要做什么不同于上面的事情吗? 谢谢。