python中的变量类型检测

时间:2015-11-27 09:42:46

标签: python typechecking duck-typing runtime-type

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

我发现可以做到了

x.__class__.__name__

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

4 个答案:

答案 0 :(得分:3)

旧式课程会失败; 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

请注意,最好使用isinstance()并接受子类,包括虚拟子类(通过abstract base classes)。不要将代码绑定到特定类型。

例如,当您可以使用obj.__class__.__name__ in ('int', 'float', 'complex')时,您不想测试isinstance(obj, numbers.Number);这样你的代码也会接受decimal.Decimal个对象。

答案 1 :(得分:2)

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

直截了当的例子是针对不同模块中定义的类(例如,考虑NodeConnection等通用常用名称。

但是,即使在单个模块中也很容易证明这个问题:

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返回的type(obj)对象。

当然,根据您使用的内容,最好使用isinstance而不是直接处理type个对象。

答案 2 :(得分:1)

在Python 2.x中检测字符串的一个常见问题是混合strunicode类型。

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'

答案 3 :(得分:1)

你真的不应该调用 magic 函数,你可以使用type()isinstance()。两者之间的主要区别在于isinstance()支持继承,因此如果您的类继承自其他类,则可能需要使用isinstance()