为什么type(classInstance)返回'实例'?

11 投票
3 回答
6266 浏览
提问于 2025-04-16 00:23

我有一个方法,它可以接收几种不同类型的参数,然后根据参数的类型做不同的事情。但是,当我检查这个参数的类型时,我总是得到 <type 'instance'>,这让我在比较时遇到了麻烦。

我有类似这样的代码:

from classes import Class1
from classes import Class2
# Both classes are declared in the same file.
# I don't know if that can be a problem         #
# ... #
def foo(parameter)
    if (type(parameter) == type(Class1()):
    # ... #
    elif (type(parameter) == type(Class2()):
    # ... #

因为 type(parameter) 返回的是 <type 'instance'>,而 type(Class1()) 也是 <type 'instance'>,所以即使参数是 Class2 的实例,它也会进入第一个比较...

顺便说一下,使用 str(parameter.__class__) 可以正确显示 classes.Class1。我想我可以一直使用这个方法,但我想搞清楚到底发生了什么... 我做过很多这样的比较,之前都能正常工作...

谢谢!! :)

3 个回答

9

在Python中,使用type(x)这个命令时,对于所有旧式类的实例x,它返回的类型对象都是一样的。这是旧式类的一大缺陷,让人很烦恼。不过,遗憾的是,为了兼容旧代码,这些旧式类在Python 2.*中仍然存在,并且是没有基类的类的默认选择。

不过,除非你不得不维护一堆旧的代码(而且这些代码没有好的测试工具让你放心去改动),否则不要使用旧式类。如果一个类没有“自然”的基类,最好是从object继承,而不是从什么都不继承。或者,你可以在模块的最上面设置

__metaclass__ = type

这样可以把默认的旧式类换成新的风格类。虽然通常建议明确地从object继承(“明确优于隐含”),但在一些旧模块中,使用模块全局的__metaclass__设置可能会让人感觉“更不干扰”,适合那些正在从旧类切换到新类的情况,所以这里提供了这个选项。

10

你真的应该使用 isinstance 这个函数:

In [26]: def foo(param):
   ....:     print type(param)
   ....:     print isinstance(param, Class1)
   ....:

In [27]: foo(x)
<type 'instance'>
True

对于内置类型,使用 type 会更好。

16

老式的类是这样做的。你在定义类的时候,要从 object 这个基础类派生(继承)你的类。

撰写回答