찾다
백엔드 개발파이썬 튜토리얼Python 2.7.x와 3.x 버전 간의 중요한 차이점

이 글은 주로 Python 2.7.x와 3.x 버전의 중요한 차이점을 요약해서 소개합니다. 도움이 필요한 친구들이 참고하면 됩니다.

많은 Python 초보자들은 어떤 버전의 Python을 배워야 할까요? 이 질문에 대한 나의 대답은 일반적으로 "먼저 자신에게 가장 적합한 Python 튜토리얼을 선택하십시오. 튜토리얼에 사용되는 Python 버전이 무엇이든 해당 버전을 사용하십시오. 거의 완료되면 다른 버전 간의 차이점을 연구할 수 있습니다."

그런데 Python으로 새 프로젝트를 개발하고 싶다면 Python 버전을 어떻게 선택하나요? 대부분의 Python 라이브러리는 Python 2.7.x와 3.x 버전을 모두 지원하므로 어떤 버전을 선택하든 괜찮습니다. 그러나 Python을 사용할 때 특정 버전에서 흔히 발생하는 함정을 피하거나 Python 프로젝트를 이식해야 할 때 두 가지 일반적인 Python 버전 간의 주요 차이점을 이해하는 것이 필요합니다.

Directory

  • __future__ 모듈 사용

  • 인쇄 기능

  • 정수 나누기

  • 유니코드

  • xrange

  • 트리거 예외

  • 예외 처리

  • next() 함수 및 .next() 메서드

  • 루프 변수 및 전역 네임스페이스 누출

  • 주문형

  • input()을 사용하여 입력 콘텐츠 구문 분석

  • 목록 대신 반복 가능한 객체 반환

  • Python 2 및 Python 3에 대한 추가 기사

__future__ 모듈

[테이블로 돌아가기 목차]

Python 3.x에는 Python 2와 호환되지 않는 일부 키워드와 기능이 도입되었습니다. Python 2에서는 이러한 새로운 내용을 내장된 __future__ 모듈을 통해 가져올 수 있습니다. Python 2 환경에서 작성된 코드를 Python 3.x에서도 실행하려면 __future__ 모듈을 사용하는 것이 좋습니다. 예를 들어 Python 2에서 Python 3.x의 정수 나누기 동작을 원할 경우 다음 명령문을 사용하여 해당 모듈을 가져올 수 있습니다.

from __future__ import pision

다음 표에는 __future__에서 가져올 수 있는 다른 기능이 나열되어 있습니다.

PEP 227 3.0 PEP 2383.0PEP 3282.6PEP 3433.0PEP 31053.0PEP 3112
features 선택 버전 필수 버전 효과
nested_scopes 2.1.0b1 2 .2
pision2.2.0a2
: pision 연산자 변경
absolute_import2.5.0a1
: 수입품: 멀티 -라인 및 절대/상대
with_statement2.5.0a1
: "with" 문
print_function 2.6.0a2
: 함수 인쇄 만들기
unicode_literals2.6.0a2
: Python 30의 바이트 리터럴 00

(来源: https://docs.python.org/2/library/future.html)

示例:

from platform import python_version

print函数

[回到目录]

虽然print语法是Python 3中一个很小的改动,且应该已经广为人知,但依然值得提一下:Python 2中的print语句被Python 3中的print()函数取代,这意味着在Python 3中必须用括号将需要输出的对象括起来。

在Python 2中使用额外的括号也是可以的。但反过来在Python 3中想以Python2的形式不带括号调用print函数时,会触发SyntaxError。

Python 2

print 'Python', python_version()
print 'Hello, World!'
print('Hello, World!')
print "text", ; print 'print more text on the same line'
Python 2.7.6
Hello, World!
Hello, World!
text print more text on the same line

Python 3

print('Python', python_version())
print('Hello, World!')
 
print("some text,", end="") 
print(' print more text on the same line')
Python 3.4.1
Hello, World!
some text, print more text on the same line
print 'Hello, World!'
File "", line 1
print 'Hello, World!'
^
SyntaxError: invalid syntax

注意:

在Python中,带不带括号输出”Hello World”都很正常。但如果在圆括号中同时输出多个对象时,就会创建一个元组,这是因为在Python 2中,print是一个语句,而不是函数调用。

print 'Python', python_version()
print('a', 'b')
print 'a', 'b'
Python 2.7.7
('a', 'b')
a b

整数除法

[回到目录]

由于人们常常会忽视Python 3在整数除法上的改动(写错了也不会触发Syntax Error),所以在移植代码或在Python 2中执行Python 3的代码时,需要特别注意这个改动。

所以,我还是会在Python 3的脚本中尝试用float(3)/2或 3/2.0代替3/2,以此来避免代码在Python 2环境下可能导致的错误(或与之相反,在Python 2脚本中用from __future__ import pision来使用Python 3的除法)。

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

Unicode

[回到目录]

Python 2有基于ASCII的str()类型,其可通过单独的unicode()函数转成unicode类型,但没有byte类型。

而在Python 3中,终于有了Unicode(utf-8)字符串,以及两个字节类:bytes和bytearrays。

Python 2

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

Python 3

print(&#39;Python&#39;, python_version())
print(&#39;strings are now utf-8 u03BCnicou0394é!&#39;)
Python 3.4.1
strings are now utf-8 μnicoΔé!
print(&#39;Python&#39;, python_version(), end="")
print(&#39; has&#39;, type(b&#39; bytes for storing data&#39;))
Python 3.4.1 has <class &#39;bytes&#39;>
print(&#39;and Python&#39;, python_version(), end="")
print(&#39; also has&#39;, type(bytearray(b&#39;bytearrays&#39;)))
and Python 3.4.1 also has <class &#39;bytearray&#39;>
&#39;note that we cannot add a string&#39; + b&#39;bytes for data&#39;
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
 in ()
----> 1 &#39;note that we cannot add a string&#39; + b&#39;bytes for data&#39;
 
TypeError: Can't convert 'bytes' object to str implicitly

xrange

[回到目录]

在Python 2.x中,经常会用xrange()创建一个可迭代对象,通常出现在“for循环”或“列表/集合/字典推导式”中。

这种行为与生成器非常相似(如”惰性求值“),但这里的xrange-iterable无尽的,意味着可能在这个xrange上无限迭代。

由于xrange的“惰性求知“特性,如果只需迭代一次(如for循环中),range()通常比xrange()快一些。不过不建议在多次迭代中使用range(),因为range()每次都会在内存中重新生成一个列表。

在Python 3中,range()的实现方式与xrange()函数相同,所以就不存在专用的xrange()(在Python 3中使用xrange()会触发NameError)。

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 &#39;Python&#39;, python_version()
 
print 'ntiming range()'
%timeit test_range(n)
 
print 'nntiming 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(&#39;Python&#39;, python_version())
 
print(&#39;ntiming range()&#39;)
%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)
in ()
----> 1 print(xrange(10))
 
NameError: name &#39;xrange&#39; is not defined

Python 3中的range对象中的__contains__方法

另一个值得一提的是,在Python 3.x中,range有了一个新的__contains__方法。__contains__方法可以有效的加快Python 3.x中整数和布尔型的“查找”速度。

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(&#39;Python&#39;, 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

根据上面的timeit的结果,查找整数比查找浮点数要快大约6万倍。但由于Python 2.x中的range或xrange没有__contains__方法,所以在Python 2中的整数和浮点数的查找速度差别不大。

print &#39;Python&#39;, python_version()
 
assert(val_in_xrange(x, x/2.0) == True)
assert(val_in_xrange(x, x/2) == True)
assert(val_in_range(x, x/2) == True)
assert(val_in_range(x, x//2) == True)
%timeit val_in_xrange(x, x/2.0)
%timeit val_in_xrange(x, x/2)
%timeit val_in_range(x, x/2.0)
%timeit val_in_range(x, x/2)
Python 2.7.7
1 loops, best of 3: 285 ms per loop
1 loops, best of 3: 179 ms per loop
1 loops, best of 3: 658 ms per loop
1 loops, best of 3: 556 ms per loop

下面的代码证明了Python 2.x中没有__contain__方法:

print(&#39;Python&#39;, python_version())
range.__contains__
Python 3.4.1
<slot wrapper &#39;__contains__&#39; of &#39;range&#39; objects
print(&#39;Python&#39;, python_version())
range.__contains__
Python 2.7.7
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
 in ()
1 print &#39;Python&#39;, python_version()
----> 2 range.__contains__
 
AttributeError: 'builtin_function_or_method' object has no attribute '__contains__'
print(&#39;Python&#39;, python_version())
xrange.__contains__
Python 2.7.7
 
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
in ()
1 print &#39;Python&#39;, python_version()
----> 2 xrange.__contains__
 
AttributeError: type object 'xrange' has no attribute '__contains__'

关于Python 2中xrange()与Python 3中range()之间的速度差异的一点说明:

有读者指出了Python 3中的range()和Python 2中xrange()执行速度有差异。由于这两者的实现方式相同,因此理论上执行速度应该也是相同的。这里的速度差别仅仅是因为Python 3的总体速度就比Python 2慢。

def test_while():
 i = 0
 while i < 20000:
  i += 1
 return
print(&#39;Python&#39;, python_version())
%timeit test_while()
Python 3.4.1
%timeit test_while()
100 loops, best of 3: 2.68 ms per loop
print &#39;Python&#39;, python_version()
%timeit test_while()
Python 2.7.6
1000 loops, best of 3: 1.72 ms per loop

触发异常

[回到目录]

Python 2支持新旧两种异常触发语法,而Python 3只接受带括号的的语法(不然会触发SyntaxError):

Python 2

print &#39;Python&#39;, python_version()
Python 2.7.6
raise IOError, "file error"
---------------------------------------------------------------------------
IOError Traceback (most recent call last)
 in ()
----> 1 raise IOError, "file error"
 
IOError: file error
raise IOError("file error")
---------------------------------------------------------------------------
IOError Traceback (most recent call last)
 in ()
----> 1 raise IOError("file error")
 
IOError: file error

Python 3

print(&#39;Python&#39;, python_version())
Python 3.4.1
raise IOError, "file error"
File "", line 1
raise IOError, "file error"
^
SyntaxError: invalid syntax
The proper way to raise an exception in Python 3:
print(&#39;Python&#39;, python_version())
raise IOError("file error")
Python 3.4.1
 
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
 in ()
1 print(&#39;Python&#39;, python_version())
----> 2 raise IOError("file error")
 
OSError: file error

异常处理

[回到目录]

Python 3中的异常处理也发生了一点变化。在Python 3中必须使用“as”关键字。

Python 2

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

Python 3

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

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

[回到目录]

由于会经常用到next()(.next())函数(方法),所以还要提到另一个语法改动(实现方面也做了改动):在Python 2.7.5中,函数形式和方法形式都可以使用,而在Python 3中,只能使用next()函数(试图调用.next()方法会触发AttributeError)。

Python 2

print &#39;Python&#39;, python_version()
my_generator = (letter for letter in 'abcdefg')
next(my_generator)
my_generator.next()
Python 2.7.6
&#39;b&#39;

Python 3

print(&#39;Python&#39;, python_version())
my_generator = (letter for letter in 'abcdefg')
next(my_generator)
Python 3.4.1
&#39;a&#39;
my_generator.next()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-14-125f388bb61b> in <module>()
----> 1 my_generator.next()
 
AttributeError: &#39;generator&#39; object has no attribute &#39;next&#39;

For循环变量与全局命名空间泄漏

[回到目录]

好消息是:在Python 3.x中,for循环中的变量不再会泄漏到全局命名空间中了!

这是Python 3.x中做的一个改动,在“What's New In Python 3.0”中有如下描述:

“列表推导不再支持[... for var in item1, item2, ...]这样的语法,使用[... for var in (item1, item2, ...)]代替。还要注意列表推导有不同的语义:现在列表推导更接近list()构造器中的生成器表达式这样的语法糖,特别要注意的是,循环控制变量不会再泄漏到循环周围的空间中了。”

Python 2

print &#39;Python&#39;, 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(&#39;Python&#39;, 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

比较无序类型

[回到目录]

Python 3中另一个优秀的改动是,如果我们试图比较无序类型,会触发一个TypeError。

Python 2

print &#39;Python&#39;, 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] > &#39;foo&#39; = False
(1, 2) > &#39;foo&#39; = True
[1, 2] > (1, 2) = False

Python 3

print(&#39;Python&#39;, 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)
 in ()
1 print(&#39;Python&#39;, 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()

通过input()解析用户的输入

[回到目录]

幸运的是,Python 3改进了input()函数,这样该函数就会总是将用户的输入存储为str对象。在Python 2中,为了避免读取非字符串类型会发生的一些危险行为,不得不使用raw_input()代替input()。

Python 2

Python 2.7.6
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
 
>>> my_input = input('enter a number: ')
 
enter a number: 123
 
>>> type(my_input)

 
>>> my_input = raw_input('enter a number: ')
 
enter a number: 123
 
>>> type(my_input)
<type &#39;str&#39;>

Python 3

Python 3.4.1
[GCC 4.2.1 (Apple Inc. build 5577)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
 
>>> my_input = input(&#39;enter a number: &#39;)
enter a number: 123
>>> type(my_input)
<class &#39;str&#39;>

返回可迭代对象,而不是列表

[回到目录]

在xrange一节中可以看到,某些函数和方法在Python中返回的是可迭代对象,而不像在Python 2中返回列表。

由于通常对这些对象只遍历一次,所以这种方式会节省很多内存。然而,如果通过生成器来多次迭代这些对象,效率就不高了。

此时我们的确需要列表对象,可以通过list()函数简单的将可迭代对象转成列表。

Python 2

print &#39;Python&#39;, python_version()
 
print range(3)
print type(range(3))
Python 2.7.6
[0, 1, 2]
<type &#39;list&#39;>

Python 3

print(&#39;Python&#39;, python_version())
print(range(3))
print(type(range(3)))
print(list(range(3)))
Python 3.4.1
range(0, 3)
<class &#39;range&#39;>
[0, 1, 2]

下面列出了Python 3中其他不再返回列表的常用函数和方法:

  • zip()

  • map()

  • filter()

  • 字典的.key()方法

  • 字典的.value()方法

  • 字典的.item()方法

更多关于Python 2和Python 3的文章

[回到目录]

下面列出了其他一些可以进一步了解Python 2和Python 3的优秀文章,

//迁移到 Python 3

  • Should I use Python 2 or Python 3 for my development activity?

  • What's New In Python 3.0

    Python Python 3 Belittle 3 Belittle Pythlit
  • 10 Python 3

  • Python 3으로 업그레이드하기 때문에 사용할 수없는 파이썬의 멋진 기능

  • Python 3는 괜찮습니다

위 내용은 Python 2.7.x와 3.x 버전 간의 중요한 차이점의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
详细讲解Python之Seaborn(数据可视化)详细讲解Python之Seaborn(数据可视化)Apr 21, 2022 pm 06:08 PM

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于Seaborn的相关问题,包括了数据可视化处理的散点图、折线图、条形图等等内容,下面一起来看一下,希望对大家有帮助。

详细了解Python进程池与进程锁详细了解Python进程池与进程锁May 10, 2022 pm 06:11 PM

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于进程池与进程锁的相关问题,包括进程池的创建模块,进程池函数等等内容,下面一起来看一下,希望对大家有帮助。

Python自动化实践之筛选简历Python自动化实践之筛选简历Jun 07, 2022 pm 06:59 PM

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于简历筛选的相关问题,包括了定义 ReadDoc 类用以读取 word 文件以及定义 search_word 函数用以筛选的相关内容,下面一起来看一下,希望对大家有帮助。

归纳总结Python标准库归纳总结Python标准库May 03, 2022 am 09:00 AM

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于标准库总结的相关问题,下面一起来看一下,希望对大家有帮助。

分享10款高效的VSCode插件,总有一款能够惊艳到你!!分享10款高效的VSCode插件,总有一款能够惊艳到你!!Mar 09, 2021 am 10:15 AM

VS Code的确是一款非常热门、有强大用户基础的一款开发工具。本文给大家介绍一下10款高效、好用的插件,能够让原本单薄的VS Code如虎添翼,开发效率顿时提升到一个新的阶段。

python中文是什么意思python中文是什么意思Jun 24, 2019 pm 02:22 PM

pythn的中文意思是巨蟒、蟒蛇。1989年圣诞节期间,Guido van Rossum在家闲的没事干,为了跟朋友庆祝圣诞节,决定发明一种全新的脚本语言。他很喜欢一个肥皂剧叫Monty Python,所以便把这门语言叫做python。

Python数据类型详解之字符串、数字Python数据类型详解之字符串、数字Apr 27, 2022 pm 07:27 PM

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于数据类型之字符串、数字的相关问题,下面一起来看一下,希望对大家有帮助。

详细介绍python的numpy模块详细介绍python的numpy模块May 19, 2022 am 11:43 AM

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于numpy模块的相关问题,Numpy是Numerical Python extensions的缩写,字面意思是Python数值计算扩展,下面一起来看一下,希望对大家有帮助。

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구