2010-06-24 65 views
10

我有一个方法,接受一个参数可以是几种类型,并根据类型必须做一件事或其他,但如果我检查所述参数的类型,我不会得到'真正'类型,我总是得到<type 'instance'>,这正在搞乱我的比较。为什么type(classInstance)返回'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。我想我总是可以使用它,但我想知道发生了什么...我做了这样的比较的十分之一和所有他们正常工作...

谢谢! :)

回答

15

旧式课程可以做到这一点。在他们的定义中从object派生你的类。

+0

Wooo ...这工程! :) 现在我要试图找出“为什么”...:D – BorrajaX 2010-06-24 14:15:03

+0

它与新风格的类有更多的元数据,包括'type()'触及的东西有关。 – 2010-06-24 14:21:26

+0

Thx再次,我正在阅读: http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html 而我种(类)认为这样的事情必须是原因 – BorrajaX 2010-06-24 14:38:45

10

应该要使用isinstance:

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

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

类型是内置类型更好。

+0

宇!谢谢你的真快的答案... 我认为,但后来我读了这一点: http://www.canonical.org/~kragen/isinstance/ 我胆怯了...:S 虽然我必须说,另一方面,'isinstance'我适合我的需要...... – BorrajaX 2010-06-24 14:06:26

+2

'isinstance'通常更适合直接使用'type()'检查,并且绝对是您在实际为每个检查实例化'Class1()'时使用的类型检查方式。然而,该文章所说的是,在许多情况下,检查类型*(无论使用哪种方法)都是错误编码实践的标志。国际海事组织的文章没有帮助,并且仍然有效用于类型检查,但是如果您对自己定义的类型进行了“数十次”检查,听起来像是一种潜在的“不够面向对象”的代码味道。 – bobince 2010-06-24 14:16:43

+0

您可以在Ops代码中清楚地看到为什么进行类型检查意味着您不*执行OOP:'if isinstace(obj,Cls)'应该在Cls的方法中后面会出现什么代码。这可能听起来很虔诚,但如果你想使用面向对象(不是你必须的),那么你必须至少得到*正确的。 – 2010-06-24 14:34:25

9

type(x)返回相同类型对象的所有实例x传统,又名旧式类,是这些类的许多真气缺陷之一 - 不幸的是他们必须保持(并成为默认值对于没有基类的类)在Python 2.*出于向后兼容的原因。

然而,不使用旧式类,除非你被迫维护一堆旧的,遗留的代码(没有一个好的测试套件让你有信心尝试和切换类o类)。当一个班级没有“天然”基地时,从object开始进行分类,而不是从无到有。或者,你的模块,在顶部,可以设置

__metaclass__ = type 

从而改变从这些混沌,传统的老式类的默认,给光泽亮丽新型的 - 而明确地object继承通常是首选(“显式优于隐式”),模块全局设置__metaclass__可能会对现有的旧模块感到“侵入性较差”,因为您将从旧模块切换到新类,因此可能会提供这种模块。

+0

谢谢!太好了!我已经使用了伊格纳西奥提出的那个。但是......最后,如果我的理解是正确的,他们是非常相似的,对吧? – BorrajaX 2010-06-25 15:01:46

+0

@Borrajax,从'object'显示继承的最终结果vs不是继承,并且有一个模块 - 全局的'__metaclass __ = type'完全一样 - 风格非常不同,不可区分的结果。 – 2010-06-25 22:18:05