程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

对象在动态类型创建期间被子类化,但在python2中的经典类定义期间不被子类化

发布于2019-09-26 15:55     阅读(1048)     评论(0)     点赞(7)     收藏(2)


我们知道这会创建一个类:

class X:
    a = 1

并且,在Python 3中,由于使用了新的样式类,因此会X自动从继承object,但是在Python 2中,它不会:

>>> X.__bases__ # Python 2
()
>>> X.__bases__ # Python 3
(<class 'object'>,)

我们也知道,我们可以使用类工厂动态创建这样的一个类:

X = type("X",(object,), {"a":1})
      name^   ^bases     ^ "class" body

然而,如果我们忽略了object基地的元组就像我们用做class语法,我们继承object的python3和,出乎意料的是,在python2还有:

X = type("X", ( ), {"a":1})
               ^ empty bases tuple
>>> X.__bases__ # Python 2
(<type 'object'>,)
>>> X.__bases__ # Python 3
(<class 'object'>,)

我期望X.__bases__在python 2中是空的。
这不是一个文档化的功能,我几乎无法在Internet上找到有关此功能的信息。

实际上,python的官方文档矛盾地指出:

基元组逐项列出基类并成为__bases__属性

但是,如上所示,它()仍然会(<type 'object'>,)在Python 2中生成,因此将它变成__bases__属性并不是真的

谁能解释这种行为?


解决方案


让我们看看这个Python 2 shell。

>>> class X1:
...     a = 1
... 
... X2 = type('X2', (), {'a': 1})
>>> type(X1)
0: <type 'classobj'>
>>> type(X2)
1: <type 'type'>
>>> import types
>>> assert types.ClassType is type(X1)

types.ClassType 被描述为:

用户定义的旧类的类型。

基本上type在新样式类的默认元类中。如果要使用旧样式的元编程,则可以types.ClassType以相同的方式使用。

>>> X3 = types.ClassType('X3', (), {'a': 1})
>>> X3.__bases__
2: () 

作为参考,摘录自Python 2的New-class和classic类

类和实例有两种风格:旧样式(或经典样式)和新样式。

在Python 2.1之前,的概念class与的概念无关 type,而旧式类是唯一可用的样式。对于老式类,该语句x.__class__提供x的类,但 type(x)始终为<type 'instance'>这反映了一个事实,即所有旧式实例(独立于其类)均使用称为的单个内置类型实现instance

新样式类在Python 2.2引入了统一的概念 classtype新型类只是用户定义的类型,不多也不少。如果x是新样式类的实例,则type(x) 通常与x相同x.__class__(尽管不能保证-允许新样式类实例覆盖为返回的值 x.__class__)。



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:https://www.pythonheidong.com/blog/article/122796/124f7f52b2f2a5ef61d6/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

7 0
收藏该文
已收藏

评论内容:(最多支持255个字符)