python中的变量类型检测

python中的变量类型检测,python,typechecking,duck-typing,runtime-type,Python,Typechecking,Duck Typing,Runtime Type,我正在研究python(2.5+)中检测变量类型(列表与字符串)的方法,并找到了一些似乎过于复杂的其他答案 我找到了一个可以做的 x.__class__.__name__ 获取包含类名的字符串。如果有什么问题的话,这有什么问题?它不是便携式的吗?什么时候它会失败?对于旧式的课程它会失败isinstance()工作正常: >>> class OldStyle: pass ... >>> OldStyle.__class__.__name__ Traceback

我正在研究python(2.5+)中检测变量类型(列表与字符串)的方法,并找到了一些似乎过于复杂的其他答案

我找到了一个可以做的

x.__class__.__name__

获取包含类名的字符串。如果有什么问题的话,这有什么问题?它不是便携式的吗?什么时候它会失败?

对于旧式的课程它会失败<代码>isinstance()工作正常:

>>> class OldStyle: pass
...
>>> OldStyle.__class__.__name__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class OldStyle has no attribute '__class__'
>>> isinstance(OldStyle(), OldStyle)
True
>>类旧样式:通过
...
>>>旧样式。\uuuuuu类\uuuuuuuuu名称__
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:类OldStyle没有属性“\uuuuu类\uuuuuu”
>>>isinstance(OldStyle(),OldStyle)
真的
请注意,最好使用
isinstance()
并接受子类,包括虚拟子类(via)。不要将代码绑定到特定类型


例如,您不想在('int'、'float'、'complex')中测试
obj.\uuuu类\uuuuu.\uuuuu名\uuuuuuuuuu,当您可以使用
isinstance(obj,numbers.Number)
时;这样,您的代码将接受
decimal.decimal
对象。

问题是不同的类可以有相同的名称

简单的例子是在不同模块中定义的类(例如,想想通用的通用名称,例如
节点
连接

但是,即使在单个模块中也很容易演示此问题:

class A(object): pass
B = A
class A(object): pass
C = A

b = B()
c = C()
b.__class__.__name__ == c.__class__.__name__
=> True
type(b) == type(c)
=> False
如果不需要类的字符串表示,只需使用调用
type(obj)
返回的
type
对象即可


当然,根据您使用它的目的,最好使用
isinstance
而不是直接处理
类型
对象。

在Python2.x中检测字符串的一个常见错误是将
str
unicode
类型混淆

assert isinstance("", str) is True
assert isinstance(u"", str) is True  # AssertionError!
assert isinstance(u"", unicode) is True
assert isinstance(u"", unicode) is True
assert isinstance("", unicode) is True  # AssertionError!
# Both lines below are always correct
assert isinstance("", basestring) is True
assert isinstance(u"", basestring) is True
正如您所看到的,所有字符串都派生自相同的基类——这就是允许统一类型检查的原因。无法使用类名字符串查找

>>> "".__class__.__name__
'str'
>>> u"".__class__.__name__
'unicode'

您实际上不应该调用神奇函数,您可以使用
type()
isinstance()
。两者之间的主要区别在于
isinstance()
支持继承,因此如果您的类继承自其他类,那么您可能想使用
isinstance()

好吧,但是使用
isinstance()
有什么问题吗?
type()呢
method?@doublep完全没有什么——这只是突出了我的误解:)谢谢,这里的类型对象是我困惑的部分原因。