我有一些用python 2.7.x编写的代码,我试图与python 3.x兼容。我已经解决了将代码转换为在两个版本下工作的大多数问题,但是想要处理int / long类型的建议。
统一int和long类型的大部分工作都发生在早期版本(2.4.x)中,并且在V3中完全消除了区别('1L'格式不再有效)。同时修改了types模块以删除对已经内置的类型的引用,并删除了冗余的“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,没有内置类很长,并且不需要do_long_stuff与普通的do_int_stuff不同。不再定义内置类类型变量'long',因此此代码将因NameError而失败。
一个简单的解决方案是在v3下将'long'定义为None或其他一些无意义类型,理解类型(var)!= long for any var。在v2.x下定义的长内置类类型将保持不变。
if sys.version_info.major == 3 :
long = None
没有最佳价值吗?在我的情况下,设置'long = int'不是我想要使用的。
答案 0 :(得分:5)
首先,你永远不应该使用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):
请注意,我在此更改了基于integer_types
的{{1}}定义,而不是版本测试。现在,您的代码兼容Python 2和3,以及任何其他没有NameError
类型的假设Python构建。
答案 1 :(得分:4)
通常,如果我要在python中进行类型检查,我更愿意在可能的情况下检查抽象基类。在这种情况下,存在numbers.Integral
可能很好地工作......
>>> import numbers
>>> isinstance(1, numbers.Integral)
True
>>> isinstance(1L, numbers.Integral)
True
>>> isinstance(1., numbers.Integral)
False
这应该适用于python2.x和python3.x。
当然,这个答案(以及到目前为止提出的所有其他答案)都假设您实际上想要做同样的事情,如果数字是int
或 a {{1} }。
任何想要根据它是否具有long
或int
而做出不同的事情的代码看起来都很可怕而且尝试将其直接移植到python3.x是没有希望的,因为long
根本没有存在使得代码路径实际上已经死亡。
答案 2 :(得分:0)
我喜欢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)