In [1]: def fun(x,y): return x + y In [2]: class A: ...: cvar = 1 ...: cfun = fun ...: def __init__(self): ...: self.ivar = 100 ...: self.ifun = fun
我们可以看到int类的类变量和实例变量都可以正常工作:
In [3]: a = A() In [4]: a.ivar,a.cvar Out[4]: (100,1)
但是,如果检查函数类型变量,情况就会改变:
In [5]: a.ifun,a.cfun Out[5]: (<function __main__.fun>,<bound method A.fun of <__main__.A instance at 0x25f90e0>>) In [6]: a.ifun(1,2) Out[6]: 3 In [7]: a.cfun(1,2) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/future/<ipython-input-7-39aa8db2389e> in <module>() ----> 1 a.cfun(1,2) TypeError: fun() takes exactly 2 arguments (3 given)
我知道python已将a.cfun(1,2)转换为A.cfun(a,1,2),然后引发错误.
我的问题是:既然cvar和cfun都是类变量,为什么python以不同的方式对待它们?
解决方法
def x():pass class A: f = x e = None g = None print(A.__dict__['f']) # <function x at 0x10e0a6e60>
当您从实例中检索它时,它会动态转换为方法对象:
print(A().f) # <bound method A.x of <__main__.A instance at 0x1101ddea8>>
http://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy“用户定义的方法”:
user-defined method objects may be created when getting an attribute of a class (perhaps via an instance of that class),if that attribute is a user-defined function object,an unbound user-defined method object,or a class method object… Note that the transformation from function object to (unbound or bound) method object happens each time the attribute is retrieved from the class or instance.
此转换仅发生在分配给类的函数中,而不发生在实例上.请注意,这已在Python 3中更改,其中Class.fun返回正常函数,而不是“未绑定方法”.
至于你的问题为什么需要它,方法对象本质上是一个包含函数及其执行上下文(“self”)的闭包.想象一下,你有一个对象并将其方法用作某个回调.在许多其他语言中,您必须传递对象和方法指针或手动创建闭包.例如,在javascript中:
myListener = new Listener() something.onSomeEvent = myListener.listen // won't work! something.onSomeEvent = function() { myListener.listen() } // works
Python在幕后为我们管理:
myListener = Listener() something.onSomeEvent = myListener.listen // works
另一方面,有时在类中使用“裸”函数或“外来”方法是切实可行的:
def __init__(...,dir,..): self.strip = str.lstrip if dir == 'ltr' else str.rstrip ... def foo(self,arg): self.strip(arg)
上述约定(class vars => methods,instance vars => functions)提供了一种方便的方法.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。