six.PY2 返回一个表示当前运行环境是否为python2的boolean值
six.PY3 返回一个表示当前运行环境是否为python3的boolean值
import six,sysprint(six.PY2) #python2结果为True
print(six.PY3) #python3结果为Truesys.version_info[0] #PY2 = 2
sys.version_info[0] #PY3 = 3
sys.version_info[0:2] #PY34>= (3, 4)
这里主要是针对python中的old-style和new-style, new-style为type, old-style为 types.ClassType。
python2中同时有old-style和new-style,python3中只有new-style。
这里针对python2和python3中各自支持的int类型进行了区分:在python2中,存在 int 和 long 两种整数类型;在python3中,仅存在一种类型int。
这里针对python2和python3中各自的string类型进行了区分:在python2中,使用的为basestring;在python3中,使用的为str。
这里针对python2和python3中的文本字符进行了区分:在python2中,使用的文本字符的类型为unicode;在python3中使用的文本字符的类型为str。
具体可以参考Python2 与 Python3 的编码对比
list、string、dict以及其他的容器所能支持的最大尺寸。
if PY3:string_types = str,integer_types = int,class_types = type,text_type = strbinary_type = bytesMAXSIZE = sys.maxsize
else:string_types &#61; basestring,integer_types &#61; (int, long)class_types &#61; (type, types.ClassType)text_type &#61; unicodebinary_type &#61; strif sys.platform.startswith("java"):# Jython always uses 32 bits.MAXSIZE &#61; int((1 <<31) - 1)else:# It&#39;s possible to have sizeof(long) !&#61; sizeof(Py_ssize_t).class X(object):def __len__(self):return 1 <<31try:len(X())except OverflowError:# 32-bitMAXSIZE &#61; int((1 <<31) - 1)else:# 64-bitMAXSIZE &#61; int((1 <<63) - 1)del X
针对python2和python3中unbound function的支持不同&#xff0c;在python2中存在unbound function&#xff0c;在python3中不存在unbound function。
if PY3:def get_unbound_function(unbound):return unbound
else:def get_unbound_function(unbound):return unbound.im_func
有关的测试代码如下:
>>> class Foo():
... def bar():
... print(1)
... def too(self):
... print(2)
...
>>>
在python2的环境中&#xff1a;
>>> Foo.bar
>>> Foo().bar
>>> Foo.too
>>> Foo().too
在python3的环境中&#xff1a;
>>> Foo.bar
>>> Foo().bar
>>> Foo.too
>>> Foo().bar
使用six.get_unbound_function(meth)&#xff1a;
在python2环境中&#xff1a;
>>> import six
>>> six.get_unbound_function(Foo.too)
>>> six.get_unbound_function(Foo.bar)
在python3环境中&#xff1a;
>>> import six
>>> six.get_unbound_function(Foo.too)
>>> six.get_unbound_function(Foo.bar)
此方法可以在方法对象之外得到函数。在python2中使用im_func, 在python3中使用__func__
。
if PY3:_meth_func &#61; "__func__"
else:_meth_func &#61; "im_func"
get_method_function &#61; operator.attrgetter(_meth_func)
有关的测试代码如下:
>>> class Foo():
... def bar():
... print(1)
... def too(self):
... print(2)
...
>>>
在python2环境中&#xff1a;
>>> import six
>>> six.get_method_function(Foo().bar)
>>> six.get_method_function(Foo.bar)
>>> six.get_method_function(Foo().too)
>>> six.get_method_function(Foo.too)
在python3环境中&#xff1a;
>>> import six
>>> six.get_method_function(Foo.bar)
Traceback (most recent call last):File "
AttributeError: &#39;function&#39; object has no attribute &#39;__func__&#39;
>>> six.get_method_function(Foo().bar)
>>> six.get_method_function(Foo.too)
Traceback (most recent call last):File "
AttributeError: &#39;function&#39; object has no attribute &#39;__func__&#39;
>>> six.get_method_function(Foo().too)
针对python2以及python3中的不同&#xff0c;返回bound method的self。其中&#xff1a;python2中使用im_self&#xff0c;python3中使用__self__。
if PY3:_meth_self &#61; "__self__"
else:_meth_self &#61; "im_self"
get_method_self &#61; operator.attrgetter(_meth_self)
有关的测试代码如下:
>>> class Foo():
... def bar():
... print(1)
... def too(self):
... print(2)
...
>>>
在python2的环境中&#xff1a;
>>> import six
>>> six.get_method_self(Foo.bar)
>>> a &#61; six.get_method_self(Foo.bar)
>>> a
>>> six.get_method_self(Foo().bar)
<__main__.Foo instance at 0x10563da70>
>>> a &#61; six.get_method_self(Foo().bar)
>>> a
<__main__.Foo instance at 0x10563dd88>
>>> six.get_method_self(Foo.too)
>>> a &#61; six.get_method_self(Foo.too)
>>> a
>>> six.get_method_self(Foo().too)
<__main__.Foo instance at 0x10563da28>
>>> a &#61; six.get_method_self(Foo().too)
>>> a
<__main__.Foo instance at 0x10563da70>
在python3的环境中&#xff1a;
>>> import six
>>> six.get_method_self(Foo.bar)
Traceback (most recent call last):File "
AttributeError: &#39;function&#39; object has no attribute &#39;__self__&#39;
>>> six.get_method_self(Foo().bar)
<__main__.Foo object at 0x1059bbb00>
>>> six.get_method_self(Foo.too)
Traceback (most recent call last):File "
AttributeError: &#39;function&#39; object has no attribute &#39;__self__&#39;
>>> six.get_method_self(Foo().too)
<__main__.Foo object at 0x1059bbb38>
针对python2和python3中的不同&#xff0c;返回函数当中的闭包。其中&#xff0c;python2使用func_closure&#xff0c;python3使用 closure。
if PY3:_func_closure &#61; "__closure__"
else:_func_closure &#61; "func_closure"get_function_closure &#61; operator.attrgetter(_func_closure)
关于闭包的理解可以参考:
有关的测试代码如下&#xff1a;
>>> def foo(n):
... a &#61; 1
... def bar(n):
... return a-n
... return bar
此处需要注意的是foo函数返回的是bar函数&#xff0c;而不是具体的值。
在python2的环境当中&#xff1a;
>>> foo.__closure__
>>> foo(1)
>>> foo(1).__closure__
(
>>> foo(1).func_closure
(
在python3的环境当中&#xff1a;
>>> foo.__closure__
>>> foo(1)
>>> foo(1).__closure__
(
>>> foo(1).func_closure
Traceback (most recent call last):File "
AttributeError: &#39;function&#39; object has no attribute &#39;func_closure&#39;
针对python2和python3中获取func中的code对象&#xff0c;将使用不同的方式进行获取。在python2中&#xff0c;将使用func_code&#xff1b;在python3中&#xff0c;将使用__code__。
if PY3:_func_code &#61; "__code__"
else:_func_code &#61; "func_code"
get_function_code &#61; operator.attrgetter(_func_code)
如果你对其中的code object是什么比较感兴趣&#xff0c;可以参考下面的资料&#xff1a;
有关的测试代码如下&#xff1a;
>>> def boo():
... return 1
在python2的环境当中&#xff1a;
在python3的环境当中&#xff1a; 针对python2和python3中的区别&#xff0c;获取func中的默认元组。在python2中&#xff0c;使用func_defaults&#xff1b;在python3中&#xff0c;使用 有关的测试代码如下: 在python2环境中&#xff1a; 在python3环境中: 获取函数当中的全局变量。在python2中&#xff0c;使用func_globals&#xff1b;在python3中&#xff0c;使用 有关的测试代码&#xff1a; 在python2环境中: 在python3环境中: 获取到迭代器的下一个。在python2环境中&#xff0c;使用it.next()&#xff1b;在python3环境中&#xff0c;使用next(it) 关于迭代器的内容可以参考一下文件&#xff1a; 在python2环境中&#xff1a; 在python3环境中&#xff1a; 该方法用来检验obj是否可以进行调用。 关于python的callable属性&#xff0c;请参考一下文件&#xff1a; 有关的测试代码&#xff1a; 在python2环境中&#xff1a; 在python 3.1环境中&#xff1a; 在python3.2之后的环境中&#xff1a; 来源&#xff1a;https://www.jianshu.com/p/62a6e3f2d1ca>>> boo.func_code
", line 1>
>>> boo().func_code
Traceback (most recent call last):File "
AttributeError: &#39;int&#39; object has no attribute &#39;func_code&#39;>>> boo.__code__
", line 1>
>>> boo().__code__
Traceback (most recent call last):File "
AttributeError: &#39;int&#39; object has no attribute &#39;__code__&#39;__defaults__
。if PY3:_func_defaults &#61; "__defaults__"
else:_func_defaults &#61; "func_defaults"
get_function_defaults &#61; operator.attrgetter(_func_defaults)>>> def boo(a&#61;1):
... return a
...>>> boo.func_defaults
(1,)
>>> boo.__defaults__
(1,)
>>> boo().func_defaults
Traceback (most recent call last):File "
AttributeError: &#39;int&#39; object has no attribute &#39;func_defaults&#39;
>>> boo().__defaults__
Traceback (most recent call last):File "
AttributeError: &#39;int&#39; object has no attribute &#39;__defaults__&#39;>>> boo.__defaults__
(1,)
>>> boo.func_defaults
Traceback (most recent call last):File "
AttributeError: &#39;function&#39; object has no attribute &#39;func_defaults&#39;
>>> boo().__defaults__
Traceback (most recent call last):File "
AttributeError: &#39;int&#39; object has no attribute &#39;__defaults__&#39;
>>> boo().func_defaults
Traceback (most recent call last):File "
AttributeError: &#39;int&#39; object has no attribute &#39;func_defaults&#39;__globals__
。if PY3:_func_globals &#61; "__globals__"
else:_func_globals &#61; "func_globals"
get_function_globals &#61; operator.attrgetter(_func_globals)>>> def boo(a&#61;1):
... x &#61; 100
... b &#61; x - a
... return b>>> boo.__globals__
{&#39;__builtins__&#39;:
>>> boo.func_globals
{&#39;__builtins__&#39;: >>> boo.__globals__
{&#39;__name__&#39;: &#39;__main__&#39;, &#39;__doc__&#39;: None, &#39;__package__&#39;: None, &#39;__loader__&#39;:
>>> boo.func_globals
Traceback (most recent call last):File "
AttributeError: &#39;function&#39; object has no attribute &#39;func_globals&#39;try:advance_iterator &#61; next
except NameError:def advance_iterator(it):return it.next()
next &#61; advance_iterator>>> it &#61; iter([1,2,3,4,5])
>>> while True:
... try:
... x &#61; it.next()
... except NameError:
... print "name error"
... except StopIteration:
... print "end"
... break
...
end>>> it &#61; iter([1,2,3,4,5])
>>> while True:
... try:
... x &#61; next(it)
... except NameError:
... print "name error"
... except StopIteration:
... print "end"
... break
...
end>>> it &#61; iter([1,2,3,4,5])
>>> while True:
... try:
... x &#61; it.next()
... except NameError:
... print("name error")
... except StopIteration:
... print("end")
... break
...
Traceback (most recent call last):File "
AttributeError: &#39;list_iterator&#39; object has no attribute &#39;next&#39;>>> it &#61; iter([1,2,3,4,5])
>>> while True:
... try:
... x &#61; next(it)
... except NameError:
... print("name error")
... except StopIteration:
... print("end")
... break
...
endtry:callable &#61; callable
except NameError:def callable(obj):return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)>>> def add(x, y):
... return x &#43; y
...>>> callable(add)
True>>> callable(add)
Traceback (most recent call last):File "
NameError: name &#39;callable&#39; is not defined>>> callable(add)
True