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