python2
# 查看python版本號
import platform
print(platform.python_version())
2.7.16 3.7.4
# 獲取版本號
import platform
print(platform.python_version())
1. print/exec
結論:python3中print和exec爲函數,必須使用括號
print 'Hello, World!'
exec 'print("Hello, World!")'
Hello, World! Hello, World!
print('Hello, World!')
exec('print("Hello, World!")')
Hello, World! Hello, World!
2. 編碼
結論: python的默認編碼改爲utf-8,而python2的默認編碼爲ascii。
所以通常我們在編寫包含非英文字符時,需要在python文件開頭加上 # encoding: utf-8。
而在python3中就不需要這樣的操作了。
但是實際使用中一般還是習慣性加上,因爲不清楚代碼是否有時需要在python2上執行。
import sys
print(sys.getdefaultencoding())
ascii
import sys
print(sys.getdefaultencoding())
utf-8
3. 除法
結論:python2中“/”默認是浮點除法,而python2中除法對整型是“地板除”,對浮點數據爲“浮點除”。
print 1/2
print 1.0/2
0 0.5
print(1/2)
print(1.0/2)
0.5
0.5
4. 刪掉的語法
cmp、<>不等號、xrange(其實就是range)、不再有經典類
# cmp
print cmp(1,2), cmp(1, 1), cmp(2,1)
# <> 不等號
print 1<>2
# xrange
print xrange(3)
# 經典類與新式類
class A:
pass
class B(object):
pass
a, b = A(), B()
print('a={}, b={}'.format(a, b))
print('a.__class__={}, b.__class__={}'.format(a.__class__, b.__class__))
print('type(a)={}, type(b)={}'.format(type(a), type(b)))
-1 0 1 True xrange(3) a=<__main__.A instance at 0x1082c06c8>, b=<__main__.B object at 0x1082bdc90> a.__class__=__main__.A, b.__class__=<class '__main__.B'> type(a)=<type 'instance'>, type(b)=<class '__main__.B'>
5. 拋出和捕獲異常
結論: python3中拋出的和捕獲的異常都是採用面向對象的構造函數的方式,避免了python2中奇葩的方式
A = 'Not Allow'
try:
if 'Not Allow' == A:
raise ValueError, A
except ValueError, e:
print(e)
Not Allow
A = 'Not Allow'
try:
if 'Not Allow' == A:
raise ValueError(A)
except ValueError as e:
print(e)
Not Allow
6. int與long
print(type(int(1)))
print(type(long(1)))
<type 'int'> <type 'long'>
print(type(int(1)))
print(int(12345678901234567890))
print(type(long(1)))
<class 'int'> 12345678901234567890
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-15-bdcf0920f30d> in <module> 1 print(type(int(1))) 2 print(int(12345678901234567890)) ----> 3 print(type(long(1))) NameError: name 'long' is not defined
7. True與False
結論:在python3中True和False都是關鍵字,不能被賦值。 而python2中可以被賦值修改
True = '123'
print(True)
123
True = '123'
File "<ipython-input-16-39e10140ed83>", line 1 True = '123' ^ SyntaxError: can't assign to keyword
8. 迭代對象
結論: python3中將map,filter,dict.items(), dict.keys(), dict.values的返回值改爲迭代對象
b = [1,2,3,4,5]
# map函數返回迭代對象
it_map = map(lambda x:x**2, b)
print(it_map)
# filter函數返回迭代對象
it_filter = filter(lambda x:x>2, b)
print(it_filter)
# 詞典函數返回迭代對象
a = {1:'hello', 2:'python'}
print(a.items())
print(a.keys())
print(a.values())
[1, 4, 9, 16, 25] [3, 4, 5] [(1, 'hello'), (2, 'python')] [1, 2] ['hello', 'python']
b = [1,2,3,4,5]
# map函數返回迭代對象
it_map = map(lambda x:x**2, b)
print(it_map)
for x in it_map:
print(x,)
# filter函數返回迭代對象
it_filter = filter(lambda x:x>2, b)
print(it_filter)
for x in it_filter:
print(x)
# 詞典函數返回迭代對象
a = {1:'hello', 2:'python'}
for k,v in a.items():
print('k={}, v={}'.format(k, v))
for k in a.keys():
print('k={}'.format(k))
for v in a.values():
print('v={}'.format(v))
<map object at 0x105f10a90> 1 4 9 16 25 <filter object at 0x105f10950> 3 4 5 k=1, v=hello k=2, v=python k=1 k=2 v=hello v=python
9. 新增關鍵字
nonlocal、yield from、async/await、yield for
a = 12
def func():
a = 1
def func_in():
global a; # global關鍵字只能用於對全局空間中的聲明
a = 2
func_in()
print('local a = ', a)
func()
print('global, a = ', a)
('local a = ', 1) ('global, a = ', 2)
# 這裏只演示一下nonlocal的用法,其他關鍵字一般不會用到
def func():
a = 1
def func_in():
nonlocal a; # nonlocal關鍵字可以用對局部空間中的聲明
a = 2
func_in()
print('local a = ', a)
func()
local a = 2
10. input與raw_input()
結論:python3中input()函數實現python2中raw_input()函數的功能。 python3中移除了raw_input()函數。
a = input()
print('type(a)={}, a={}'.format(type(a), a))
a = raw_input()
print('type(a)={}, a={}'.format(type(a), a))
123 type(a)=<type 'int'>, a=123 123 type(a)=<type 'str'>, a=123
a = input()
print('type(a)={}, a={}'.format(type(a), a))
a = raw_input()
123
type(a)=<class 'str'>, a=123
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-1-cb01db45b25f> in <module> 1 a = input() 2 print('type(a)={}, a={}'.format(type(a), a)) ----> 3 a = raw_input() NameError: name 'raw_input' is not defined
另外知乎上有個帖子作了如下總結,可供參考:
- 統一了字符編碼支持。我特意把它拿出來放在第一條...
- 增加了新的語法。print/exec等成爲了函數,格式化字符串變量,類型標註,添加了nonlocal、yield from、async/await、yield for關鍵詞和annotations、context、traceback、qualname等dunder方法。
- 修改了一些語法。metaclass,raise、map、filter以及dict的items/keys/values方法返回迭代對象而不是列表,描述符協議,保存類屬性定義順序,保存關鍵字參數順序
- 去掉了一些語法。cmp、<>(也就是!=)、xrange(其實就是range)、不再有經典類
- 增加一些新的模塊。concurrent.futures、venv、unittest.mock、asyncio、selectors、typing等
- 修改了一些模塊。主要是對模塊添加函數/類/方法(如functools.lru_cache、threading.Barrier)或者參數。
- 模塊改名。把一些相關的模塊放進同一個包裏面(如httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib放進了http裏面,urllib, urllib2, urlparse, robotparse放進了urllib裏面),個例如SocketServer改成了socketserver,Queue改成queue等
- 去掉了一些模塊或者函數。gopherlib、md5、contextlib.nested、inspect.getmoduleinfo等。去掉的內容的原因主要是2點:1. 過時的技術產物,已經沒什麼人在用了;2. 出現了新的替代產物後者被證明存在意義不大。理論上對於開發者影響很小。
- 優化。重新實現了dict可以減少20%-25%的內存使用;提升pickle序列化和反序列化的效率;collections.OrderedDict改用C實現;通過os.scandir對glob模塊中的glob()及iglob()進行優化,使得它們現在大概快了3-6倍等.. 這些都是喜大普奔的好消息,同樣開發者不需要感知,默默的就會讓結果變得更好。
- 其他。構建過程、C的API、安全性等方面的修改,通常對於開發者不需要關心。