python3.x与python2.x的

2023-01-31 01:01:29 python3 python2

python3.x与python2.7.x都是比较流行的版本,虽然建议现在的初学者开始学习Python3.x的版本,但是还有很多的工程使用的是python2.7.x版本。观看代码的时候难免会出现一些问题。
Google上搜到比较新的python2与python3的区别。

主要区别:

1、__future__模块

如果你想在python2.x上使用python3.x的一些功能,只需要导入__future__模块里面的具体功能即可。

from __furute__ import division #比如你想在Python2中用python3中的division功能

2、print功能函数

python2中的print语句被python3中的函数print()代替,使用的时候我们必须使用括号将内容包起来,如果没有加括号的话,会被认为是语法错误:

>>> print 'Hello, World!'  #在python3中是语法错误
  File "<ipython-input-3-139a7c5835bd>", line 1
    print 'Hello, World!'
                        ^
SyntaxError: invalid syntax

3、整数除法

这个细节区别很重要,如果你的Python2的程序在python3上跑的话会出现严重错误,而解释器不会将这个看成语法错误。
所以,建议在python3中这样写:float(3)/2 或者 3/2.0,别写成3/2。这样可以避免程序从python3到python2转移过程中发生错误(当然也可以在python2中引入from __future__ import division)。

# Python 2

>>> print 'Python', python_version()
>>> print '3 / 2 =', 3 / 2
>>> print '3 // 2 =', 3 // 2
>>> print '3 / 2.0 =', 3 / 2.0
>>> print '3 // 2.0 =', 3 // 2.0

Python 2.7.6
3 / 2 = 1
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0

# Python 3

>>> print('Python', python_version())
>>> print('3 / 2 =', 3 / 2)
>>> print('3 // 2 =', 3 // 2)
>>> print('3 / 2.0 =', 3 / 2.0)
>>> print('3 // 2.0 =', 3 // 2.0)

Python 3.4.1
3 / 2 = 1.5
3 // 2 = 1
3 / 2.0 = 1.5
3 // 2.0 = 1.0

4、Unicode

python2中有ASCII str()类型,与unicode()类型区别开,但是没byte类型
在python3中全部变为Unicode(utf-8) str 类型了,还有两个位类型:byte、bytearray

# Python 2

>>> print 'Python', python_version()
Python 2.7.6
>>> print type(unicode('this is like a python3 str type'))
<type 'unicode'>
>>> print type(b'byte type does not exist')
<type 'str'>
>>> print 'they are really' + b' the same'
they are really the same
>>> print type(bytearray(b'bytearray oddly does exist though'))
<type 'bytearray'>

# Python 3

>>> print('Python', python_version())
>>> print('strings are now utf-8 \u03BCnico\u0394é!')
Python 3.4.1
strings are now utf-8 μnicoΔé!
>>> print('Python', python_version(), end="")
>>> print(' has', type(b' bytes for storing data'))
Python 3.4.1 has <class 'bytes'>
>>> print('and Python', python_version(), end="")
>>> print(' also has', type(bytearray(b'bytearrays')))
and Python 3.4.1 also has <class 'bytearray'>
'note that we cannot add a string' + b'bytes for data'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

<ipython-input-13-d3e8942ccf81> in <module>()
----> 1 'note that we cannot add a string' + b'bytes for data'


TypeError: Can't convert 'bytes' object to str implicitly

5、xrange函数

xrange()在python2.x中非常受欢迎,它一般用于创造一个可以迭代的object来实现循环或者list/set-dictionary相关等功能。
在python3中,函数range()有了xrange()的功能,故xrange()在python3中不再存在。python3中的range相当于生成器,如果想让它返回list则必须list(range(temp))

>>> import timeit

>>> n = 10000
>>> def test_range(n):
       return for i in range(n):
           pass

>>> def test_xrange(n):
       for i in xrange(n):
           pass    
# Python 2

>>> print 'Python', python_version()

>>> print '\ntiming range()'
>>> %timeit test_range(n)

>>> print '\n\ntiming xrange()'
>>> %timeit test_xrange(n)
# Python 2.7.6
timing range()
1000 loops, best of 3: 433 µs per loop
timing xrange()
1000 loops, best of 3: 350 µs per loop
Python 3
>>> print('Python', python_version())
>>> print('\ntiming range()')
>>> %timeit test_range(n)
Python 3.4.1
timing range()
1000 loops, best of 3: 520 µs per loop
print(xrange(10))
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)

<ipython-input-5-5d8f9b79ea70> in <module>()
----> 1 print(xrange(10))


NameError: name 'xrange' is not defined

Python3中range()的contains方法

range在python3中拥有了一个新的方法__contains__。这个方法可以加速对元素的”访问”,尤其对整数或者布尔型变量。

>>> x = 10000000
>>> def val_in_range(x, val):
       return val in range(x)
>>> def val_in_xrange(x, val):
       return val in xrange(x)
>>> print('Python', python_version())
>>> assert(val_in_range(x, x/2) == True)
>>> assert(val_in_range(x, x//2) == True)
>>> %timeit val_in_range(x, x/2)
>>> %timeit val_in_range(x, x//2)
Python 3.4.1
1 loops, best of 3: 742 ms per loop
1000000 loops, best of 3: 1.19 µs per loop

6、触发异常

在python2中支持两种语法表示(新的和旧的),但是在python3中则不行,使用旧语法会触发“语法错误”:

# Python 2

>>> print 'Python', python_version()
Python 2.7.6
>>> raise IOError, "file error"
---------------------------------------------------------------------------
IOError                                   Traceback (most recent call last)

<ipython-input-8-25f049caebb0> in <module>()
----> 1 raise IOError, "file error"


IOError: file error
>>> raise IOError("file error")
---------------------------------------------------------------------------
IOError                                   Traceback (most recent call last)

<ipython-input-9-6f1c43f525b2> in <module>()
----> 1 raise IOError("file error")


IOError: file error

# Python 3

>>> print('Python', python_version())
Python 3.4.1
>>> raise IOError, "file error"
  File "<ipython-input-10-25f049caebb0>", line 1
    raise IOError, "file error"
                 ^
SyntaxError: invalid syntax
# The proper way to raise an exception in Python 3:

>>> print('Python', python_version())
>>> raise IOError("file error")
Python 3.4.1



---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)

<ipython-input-11-c350544d15da> in <module>()
      1 print('Python', python_version())
----> 2 raise IOError("file error")


OSError: file error

7、处理异常

同样,python3和python2有一点小的区别,多了一个“as”小尾巴:

# Python 2

>>> print 'Python', python_version()
>>> try:
       let_us_cause_a_NameError
   except NameError, err:
       print err, '--> our error message'
Python 2.7.6
name 'let_us_cause_a_NameError' is not defined --> our error message

# Python 3

>>> print('Python', python_version())
>>> try:
       let_us_cause_a_NameError
   except NameError as err:
       print(err, '--> our error message')
Python 3.4.1
name 'let_us_cause_a_NameError' is not defined --> our error message

8、next()函数和.next()方法

因为next()(.next())是一个常用的功能函数,所有在python3中进行了小的修改(或者说小的提升),在python2中上面两个都可以用,但是在python3中,next()可以用但是.next()则会引起 AttributeError 错误

# Python 2

>>> print 'Python', python_version()

>>> my_generator = (letter for letter in 'abcdefg')

>>> next(my_generator)
>>> my_generator.next()
>
Python 2.7.6
'b'

# Python 3

>>> print('Python', python_version())

>>> my_generator = (letter for letter in 'abcdefg')

>>> next(my_generator)
Python 3.4.1
'a'

>>> my_generator.next()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

<ipython-input-14-125f388bb61b> in <module>()
----> 1 my_generator.next()


AttributeError: 'generator' object has no attribute 'next'

9、for-loop循环中的变量不再影响全局空间中的变量

在Python3.x中for-loop中的变量不再对全局变量有影响。
另外在python3的介绍中:“List解释器不再支持这样的形式[… for var in item1,item2].应该换成[… for var in (item1,item2,…)]。新版的LIst解释器可以说在list()构造器里面有一个生成器表达式,因此循环中变量不再影响上下文中的变量”

# Python 2

>>> print 'Python', python_version()
>>> i = 1
>>> print 'before: i =', i
>>> print 'comprehension: ', [i for i in range(5)]
>>> print 'after: i =', i

Python 2.7.6
before: i = 1
comprehension:  [0, 1, 2, 3, 4]
after: i = 4

# Python 3

>>> print('Python', python_version())
>>> i = 1
>>> print('before: i =', i)
>>> print('comprehension:', [i for i in range(5)])
>>> print('after: i =', i)

Python 3.4.1
before: i = 1
comprehension: [0, 1, 2, 3, 4]
after: i = 1

10、比较非有序类型

在python3中如果对不可排序的类型进行比较时,会触发TypeError类型错误。

# Python 2

>>> print 'Python', python_version()
>>> print "[1, 2] > 'foo' = ", [1, 2] > 'foo'
>>> print "(1, 2) > 'foo' = ", (1, 2) > 'foo'
>>> print "[1, 2] > (1, 2) = ", [1, 2] > (1, 2)

Python 2.7.6
[1, 2] > 'foo' =  False
(1, 2) > 'foo' =  True
[1, 2] > (1, 2) =  False

# Python 3

>>> print('Python', python_version())
>>> print("[1, 2] > 'foo' = ", [1, 2] > 'foo')
>>> print("(1, 2) > 'foo' = ", (1, 2) > 'foo')
>>> print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2))

Python 3.4.1

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

<ipython-input-16-a9031729f4a0> in <module>()
      1 print('Python', python_version())
----> 2 print("[1, 2] > 'foo' = ", [1, 2] > 'foo')
      3 print("(1, 2) > 'foo' = ", (1, 2) > 'foo')
      4 print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2))

TypeError: unorderable types: list() > str()

11、通过input()解释用户输入

Python3对input()函数进行了修整。这样它就可以将用户的输入保存为str类型。而在python2中,为了避免使用input()读入非strings类型的危险操作,通常使用raw_input()函数。

# Python 2

>>> my_input = input('enter a number: ')
enter a number: 123
>>> type(my_input)
<type 'int'>
>>> my_input = raw_input('enter a number: ')
enter a number: 123
>>> type(my_input)
<type 'str'>
Python 3

# Python 3

>>> my_input = input('enter a number: ')
enter a number: 123
>>> type(my_input)
<class 'str'>

12、返回可迭代的对象,而不是list对象

在上面我们已经对xrange的变化有所了解,一些函数或者方法在python3中会返回可迭代的对象,不像在python2中,是返回一个list。
如果Python2程序中有返回list类型的函数,移植到Python3中就需要进行修改,这很简单,只需使用list()函数即可。

# Python 2

>>> print 'Python', python_version()
>>> print range(3)
>>> print type(range(3))

Python 2.7.6
[0, 1, 2]
<type 'list'>

# Python 3

>>> print('Python', python_version())
>>> print(range(3))
>>> print(type(range(3)))
>>> print(list(range(3)))

Python 3.4.1
range(0, 3)
<class 'range'>
[0, 1, 2]

注意,有一些常用的函数在python3中不再返回list类型:
zip()
map()
filter()
dictionary’s .keys() method
dictionary’s .values() method
dictionary’s .items() method

13、Round函数

在python3中,四舍五入更“倾向于”到偶数的那一边。

# Python 2

>>> print 'Python', python_version()
Python 2.7.12
>>> round(15.5)
16.0
>>> round(16.5)
17.0

# Python 3

>>> print('Python', python_version())
Python 3.5.1
>>> round(15.5)
16
>>> round(16.5)
16

其他区别

1、编码

Python3.x源码文件默认使用utf-8编码,这就使得以下代码是合法的:

    >>> 中国 = 'china' 
    >>>print(中国) 
    china 

2、语法

1、去除了<>,全部改用!=
2、去除“,全部改用repr()
3、关键词加入as 和with,还有True,False,None
4、加入nonlocal语句。使用noclocal x可以直接指派外围(非全局)变量
5、改变了顺序操作符的行为,例如x

# python2
   guess = int(raw_input('Enter an integer : ')) # 读取键盘输入的方法 
# python3
   guess = int(input('Enter an integer : '))

7、去除掉了元组参数解包。不能def(a, (b, c)):pass这样定义函数了
8、使用了新的8进制字变量,相应地修改了oct()函数。

# python2 
 >>> 0666 
     438 
 >>> oct(438) 
     '0666' 
# python3
>>> 0666 
     SyntaxError: invalid token (<pyshell#63>, line 1) 
>>> 0o666 
     438 
>>> oct(438) 
     '0o666' 

9、增加了 2进制字变量和bin()函数

>>> bin(438) 
    '0b110110110' 
>>> _438 = '0b110110110' 
>>> _438 
    '0b110110110' 

10、扩展的可迭代解包。在python3.x里,a, b, *rest = seq和 *rest, a = seq都是合法的,只要求两点:rest是list 对象和seq是可迭代的。
11、新的super(),可以不再给super()传参数,

>>> class C(object): 
       def __init__(self, a): 
          print('C', a) 
>>> class D(C): 
       def __init(self, a): 
          super().__init__(a)  # 无参数调用super() 
>>> D(8) 
    C 8 
    <__main__.D object at 0x00D7ED90> 

12、新的metaclass语法:
class Foo(*bases, **kwds):
pass
13、支持class decorator类修饰。用法与函数decorator一样:

>>> def foo(cls_a): 
          def print_func(self): 
             print('Hello, world!') 
          cls_a.print = print_func 
          return cls_a 
>>> @foo 
    class C(object): 
      pass 
>>> C().print() 
    Hello, world! 

3、字符串和字节串

1、现在字符串只有str一种类型,和python2.x版本的unicode是一样的。
2、数据类型 :python3.x去除了long类型,现在只有一种整型——int,但它的行为就像python2.x版本的long ;新增了bytes类型,对应于python2.x的八位字符,定义一个bytes字面量的方法如下:

>>> b = b'china' 
>>> type(b) 
    <type 'bytes'> 

3、str对象和bytes对象可以使用.encode() (str -> bytes) or .decode() (bytes -> str)方法相互转化。

>>> s = b.decode() 
>>> s 
    'china' 
>>> b1 = s.encode() 
>>> b1 
    b'china' 

4、dict的.keys()、.items 和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有 dict.has_key(),用 in替代。

4、面向对象

1、引入抽象基类(Abstraact Base Classes,ABCs)。
2、容器类和迭代器类被ABCs化,所以cellections模块里的类型比python2.x多了很多。

>>> import collections 
>>> print('\n'.join(dir(collections))) 
    Callable 
    Container 
    Hashable 
    ItemsView 
    Iterable 
    Iterator 
    KeysView 
    Mapping 
    MappingView 
    MutableMapping 
    MutableSequence 
    MutableSet 
    NamedTuple 
    Sequence 
    Set 
    Sized 
    ValuesView 
    __all__ 
    __builtins__ 
    __doc__ 
    __file__ 
    __name__ 
    _abcoll 
    _itemgetter 
    _sys 
    defaultdict 
    deque 

另外,数值类型也被ABCs化。关于这两点,请参阅 PEP 3119和PEP 3141。
3、迭代器的next()方法改名为next(),并增加内置函数next(),用以调用迭代器的next()方法
4、增加了@abstractmethod和 @abstractproperty两个 decorator,编写抽象方法(属性)更加方便。

5、异常

1、所以异常都从 BaseException继承,并删除了StardardError
2、去除了异常类的序列行为和.message属性
3、用 raise Exception(args)代替 raise Exception, args语法

6、模块变动

1、移除了cPickle模块,可以使用pickle模块代替。最终我们将会有一个透明高效的模块。
2、移除了imageop模块
3、移除了 audiodev, Bastion, bsddb185, exceptions, linuxaudiodev, md5, MimeWriter, mimify, popen2,
rexec, sets, sha, stringold, strop, sunaudiodev, timing和xmllib模块
4、移除了bsddb模块(单独发布,可以从Http://www.jcea.es/prograMacion/pybsddb.htm获取)
5、移除了new模块
6、os.tmpnam()和os.tmpfile()函数被移动到tmpfile模块下
7、tokenize模块现在使用bytes工作。主要的入口点不再是generate_tokens,而是 tokenize.tokenize()

7,杂项

1、bytes对象不能hash,也不支持 b.lower()、b.strip()和b.split()方法,但对于后两者可以使用 b.strip(b’
\n\t\r \f’)和b.split(b’ ‘)来达到相同目的
2、zip()、map()和filter()都返回迭代器。而apply()、 callable()、coerce()、 execfile()、reduce()和reload ()函数都被去除了,现在可以使用hasattr()来替换 callable(). hasattr()的语法如:hasattr(string, ‘name‘)
3、string.letters和相关的.lowercase和.uppercase被去除,请改用string.ascii_letters 等
4、如果x < y的不能比较,抛出TypeError异常。2.x版本是返回伪随机布尔值的
5、getslice系列成员被废弃。a[i:j]根据上下文转换为a.getitem(slice(I, j))或 setitem
delitem调用
6、file类被废弃::

# python2
>>> file 
    <type 'file'> 
# python3
>>> file 
    Traceback (most recent call last): 
    File "<pyshell#120>", line 1, in <module> 
       file 
    NameError: name 'file' is not defined

参考链接:https://docs.python.org/3/whatsnew/3.0.html
https://www.cnblogs.com/codingmylife/arcHive/2010/06/06/1752807.html

相关文章