python – 不同类型的类变量之间有什么区别?
首先,A类有两个类变量和两个实例变量:
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“用户定义的方法”:
此转换仅发生在分配给类的函数中,而不发生在实例上.请注意,这已在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)提供了一种方便的方法. 不用添加,就像python中的其他内容一样,可以改变这种行为,即编写一个不将其函数转换为方法的类并按原样返回它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |