加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 不同类型的类变量之间有什么区别?

发布时间:2020-12-16 21:38:27 所属栏目:Python 来源:网络整理
导读:首先,A类有两个类变量和两个实例变量: In [1]: def fun(x,y): return x + yIn [2]: class A: ...: cvar = 1 ...: cfun = fun ...: def __init__(self): ...: self.ivar = 100 ...: self.ifun = fun 我们可以看到int类的类变量和实例变量都可以正常工作: In
首先,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“用户定义的方法”:

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)提供了一种方便的方法.

不用添加,就像python中的其他内容一样,可以改变这种行为,即编写一个不将其函数转换为方法的类并按原样返回它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读