支持类型统一 python 2/3 版本
Supporting types in unified python 2/3 version
我有一些代码是用 python 2.7.x 编写的,我正试图使其与 python 3.x 兼容。我已经解决了将代码转换为在两个版本下工作的大部分问题,但需要处理 int/long 类型的建议。
许多统一 int 和 long 类型的工作发生在更早的 (2.4.x) 版本中,并且在 V3 中完全删除了区别('1L' 格式不再有效)。同时,修改了类型模块以删除对已内置类型的引用,并删除了多余的 'long' 内置类型。
所以在V2.x下我仍然需要支持这样的代码:
if type(var) == int or type(var) == long :
do_stuff
或
if type(var) == int :
do_int_stuff
elif type(var) == long :
do_long_stuff
但是对于 V3 来说,长期没有内置 class,也不需要 do_long_stuff,这与正常的 do_int_stuff 不同。内置 class 类型变量 'long' 不再定义,因此此代码将失败并出现 NameError。
一个简单的解决方案是将 'long' 定义为 None 或 v3 下的其他一些无意义的类型,理解 type(var) != long 对于任何 var。 v2.x 下定义的 long 内置 class 类型将保持不变。
if sys.version_info.major == 3 :
long = None
None 是最好的使用价值吗?在我的例子中,设置 'long = int' 不是我想要使用的。
首先,你不应该使用type(obj) == type_obj
;始终使用 isinstance()
function。你很少需要忽略子类,如果你确实需要忽略子类,你可以使用 type(obj) is type_obj
代替。
isinstance()
可以采用 元组 类型:
isinstance(obj, (int, long))
然后允许您使用变量:
try:
integer_types = (int, long)
except NameError:
integer_types = int
if isinstance(obj, integer_types):
请注意,我在这里根据 NameError
换出了 integer_types
定义,而不是在版本测试中。现在您的代码兼容 Python 2 和 3,以及任何其他没有 long
类型的假设 Python 构建。
我喜欢 Martijn 的回答,但我会把它包装成
import sys
if sys.hexversion < 0x3000000:
# Python 2.x
is_int = lambda x: isinstance(x, (int, long))
is_long = lambda x: isinstance(x, long)
else:
# Python 3.x
is_int = lambda x: isinstance(x, int)
is_long = lambda x: False
你可以像这样使用
if is_int(var):
do_something(var)
或
if is_long(var):
do_long_stuff(var)
elif is_int(var):
do_int_stuff(var)
一般来说,如果我要在 python 中进行类型检查,我更愿意尽可能检查抽象基础 class。在这种情况下,存在 numbers.Integral
可能会很好地工作...
>>> import numbers
>>> isinstance(1, numbers.Integral)
True
>>> isinstance(1L, numbers.Integral)
True
>>> isinstance(1., numbers.Integral)
False
这应该适用于 python2.x 和 python3.x。
当然,如果数字是 int
或 ,这个答案(以及迄今为止提出的所有其他答案)假设您实际上想要做同样的事情一个long
。
任何想要根据它是否具有 int
或 long
来做不同事情的代码看起来很可怕,并且尝试将其直接移植到 python3.x 作为 long
是没有希望的不存在使得该代码路径实际上已失效。
我有一些代码是用 python 2.7.x 编写的,我正试图使其与 python 3.x 兼容。我已经解决了将代码转换为在两个版本下工作的大部分问题,但需要处理 int/long 类型的建议。
许多统一 int 和 long 类型的工作发生在更早的 (2.4.x) 版本中,并且在 V3 中完全删除了区别('1L' 格式不再有效)。同时,修改了类型模块以删除对已内置类型的引用,并删除了多余的 'long' 内置类型。
所以在V2.x下我仍然需要支持这样的代码:
if type(var) == int or type(var) == long :
do_stuff
或
if type(var) == int :
do_int_stuff
elif type(var) == long :
do_long_stuff
但是对于 V3 来说,长期没有内置 class,也不需要 do_long_stuff,这与正常的 do_int_stuff 不同。内置 class 类型变量 'long' 不再定义,因此此代码将失败并出现 NameError。
一个简单的解决方案是将 'long' 定义为 None 或 v3 下的其他一些无意义的类型,理解 type(var) != long 对于任何 var。 v2.x 下定义的 long 内置 class 类型将保持不变。
if sys.version_info.major == 3 :
long = None
None 是最好的使用价值吗?在我的例子中,设置 'long = int' 不是我想要使用的。
首先,你不应该使用type(obj) == type_obj
;始终使用 isinstance()
function。你很少需要忽略子类,如果你确实需要忽略子类,你可以使用 type(obj) is type_obj
代替。
isinstance()
可以采用 元组 类型:
isinstance(obj, (int, long))
然后允许您使用变量:
try:
integer_types = (int, long)
except NameError:
integer_types = int
if isinstance(obj, integer_types):
请注意,我在这里根据 NameError
换出了 integer_types
定义,而不是在版本测试中。现在您的代码兼容 Python 2 和 3,以及任何其他没有 long
类型的假设 Python 构建。
我喜欢 Martijn 的回答,但我会把它包装成
import sys
if sys.hexversion < 0x3000000:
# Python 2.x
is_int = lambda x: isinstance(x, (int, long))
is_long = lambda x: isinstance(x, long)
else:
# Python 3.x
is_int = lambda x: isinstance(x, int)
is_long = lambda x: False
你可以像这样使用
if is_int(var):
do_something(var)
或
if is_long(var):
do_long_stuff(var)
elif is_int(var):
do_int_stuff(var)
一般来说,如果我要在 python 中进行类型检查,我更愿意尽可能检查抽象基础 class。在这种情况下,存在 numbers.Integral
可能会很好地工作...
>>> import numbers
>>> isinstance(1, numbers.Integral)
True
>>> isinstance(1L, numbers.Integral)
True
>>> isinstance(1., numbers.Integral)
False
这应该适用于 python2.x 和 python3.x。
当然,如果数字是 int
或 ,这个答案(以及迄今为止提出的所有其他答案)假设您实际上想要做同样的事情一个long
。
任何想要根据它是否具有 int
或 long
来做不同事情的代码看起来很可怕,并且尝试将其直接移植到 python3.x 作为 long
是没有希望的不存在使得该代码路径实际上已失效。