我正在研究在python(2.5+)中检测变量类型(列表与字符串)的方法,并且遇到了一些看起来过于复杂的其他答案。
我发现可以做到了
x.__class__.__name__
获取包含类名的字符串。什么,如果有的话,这是错的?它不便携吗?什么时候会失败?
答案 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)
问题是不同的类可以具有相同的名称。
直截了当的例子是针对不同模块中定义的类(例如,考虑Node
或Connection
等通用常用名称。
但是,即使在单个模块中也很容易证明这个问题:
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中检测字符串的一个常见问题是混合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'
答案 3 :(得分:1)
你真的不应该调用 magic 函数,你可以使用type()
或isinstance()
。两者之间的主要区别在于isinstance()
支持继承,因此如果您的类继承自其他类,则可能需要使用isinstance()
。