python 中的变量类型检测
Variable type detection in python
我正在研究在 python (2.5+) 中检测变量类型(列表与字符串)的方法,并遇到了一些看起来过于复杂的其他答案。
我找到了一个可以做到的
x.__class__.__name__
获取包含 class 名称的字符串。如果有的话,这有什么问题吗?它不是便携式的吗?什么时候会失败?
旧式会失败类; 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()
,接受sub类,包括virtual sub类(via abstract base classes).不要将您的代码绑定到特定类型。
例如,当您可以使用 isinstance(obj, numbers.Number)
时,您不想测试 obj.__class__.__name__ in ('int', 'float', 'complex')
;这样你的代码也将接受 decimal.Decimal
个对象。
问题是不同的 class 可以有相同的名称。
最简单的例子是针对在不同模块中定义的 classes(例如,考虑通用的通用名称,例如 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
如果您不需要 class 的字符串表示形式,只需使用通过调用 type(obj)
.
返回的 type
对象
当然,根据您的用途,最好使用 isinstance
而不是直接处理 type
对象。
检测 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 - 这就是允许统一类型检查的原因。 class 名称字符串查找是不可能的。
>>> "".__class__.__name__
'str'
>>> u"".__class__.__name__
'unicode'
你真的不应该调用 magic 函数,你可以只使用 type()
或 isinstance()
。两者之间的主要区别是 isinstance()
支持继承,所以如果你的 类 继承自其他 类 你可能想使用 isinstance()
.
我正在研究在 python (2.5+) 中检测变量类型(列表与字符串)的方法,并遇到了一些看起来过于复杂的其他答案。
我找到了一个可以做到的
x.__class__.__name__
获取包含 class 名称的字符串。如果有的话,这有什么问题吗?它不是便携式的吗?什么时候会失败?
旧式会失败类; 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()
,接受sub类,包括virtual sub类(via abstract base classes).不要将您的代码绑定到特定类型。
例如,当您可以使用 isinstance(obj, numbers.Number)
时,您不想测试 obj.__class__.__name__ in ('int', 'float', 'complex')
;这样你的代码也将接受 decimal.Decimal
个对象。
问题是不同的 class 可以有相同的名称。
最简单的例子是针对在不同模块中定义的 classes(例如,考虑通用的通用名称,例如 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
如果您不需要 class 的字符串表示形式,只需使用通过调用 type(obj)
.
type
对象
当然,根据您的用途,最好使用 isinstance
而不是直接处理 type
对象。
检测 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 - 这就是允许统一类型检查的原因。 class 名称字符串查找是不可能的。
>>> "".__class__.__name__
'str'
>>> u"".__class__.__name__
'unicode'
你真的不应该调用 magic 函数,你可以只使用 type()
或 isinstance()
。两者之间的主要区别是 isinstance()
支持继承,所以如果你的 类 继承自其他 类 你可能想使用 isinstance()
.