在python 3中,何时type()可以返回除类之外的任何东西?

时间:2018-07-21 00:48:13

标签: python python-3.x

因此,我正在浏览copy库的源代码,发现了这一点:

cls = type(x)

copier = _copy_dispatch.get(cls)
if copier:
    return copier(x)

try:
    issc = issubclass(cls, type)
except TypeError: # cls is not a class
    issc = False

重要的行是cls = type(x)except TypeError: # cls is not a class。 (以防万一,我在中间留了一行)。 except子句使我相信,对于某些xtype(x)不会返回类,但是我想不出这样的示例。 (我尝试在该子句中添加print语句,看看是否可以将其触发都没有用)。您能举一个type()不返回类的示例吗?

1 个答案:

答案 0 :(得分:9)

如果您要查询copy.copy中的支票,则实际上没有必要。这是一个长期存在的错误,但是却是一个琐碎不重要的错误,多年来一直没人愿意修复。但是,碰巧的是,它是fixed just 11 days ago的一部分,是issue 11572的一部分,该错误是一个伞形错误,旨在完成3.8的copy.py模块的代码覆盖。

这里的根本原因可以回溯到Python 2.2中存在的一个实际问题,直到2.x分支中的某个位置以后(我猜到2.5,包括端点在内,但这只是一个猜测),但未添加此修复程序直到3.4,问题才不复存在。


此检查在Python 2.x中不存在。正如user2357112所追查的那样,它是作为Python 3.4中issue 11480修复程序的一部分添加的。自定义元类的类上的copy.copy已损坏,并且有必要进行修复,该修复是从copy.deepcopy复制而来的,但其中包括不再需要的更改。后来从deepcopy中删除了,但一直停留在copy中,直到本月。


由三元组发现,原始错误是#502085

事实上,在2.2版本中,issubclass(type(x), type)提出TypeError不仅是可能的,而且实际上是在野外发生的。

在Python 2.1和更早版本中(在PEP 252之前,扩展类型基本上可以将他们想要的内容粘贴在其类型槽中。在2.2+版本中,这会破坏isinstanceissubclass。做出一个TypeError而不是段错误的做法,这已经足够好了,因为谁会在类型槽中插入非类型的字,对吗?好吧,boost::python的原始版本确实做到了为你。

下一个版本并没有引起这个问题,大概不是每个人都立即升级了(它需要重写部分代码,它不能生成与Python 2.1兼容的模块以及2MB的下载,是吗? “是在224Kbps的双ISDN上还是其他?”,所以一段时间以来,这些异常确实是一件令人担心的事情。

(这仅与旧样式类和新样式类有切线关系,即使在那之前,扩展类型实际上始终都是“新样式”,我很确定要检查其类型是否为类型是在3.0之前添加的。)


从技术上讲,在Python文档中,class一词含糊不清。有时class是通过执行class语句或调用type构造函数(或调用type的子类)而创建的。有时classtype的实例或type的子类,在这种情况下,内置类型类。

根据先前的定义,x = 1type(x)不是类的示例。但是根据后一个定义,它就是-显然是issubclass使用的定义。因此,这几乎是无关紧要的,除非您正在寻找使某人烦恼的陷阱问题。