python3.8的新增功能
本文介紹了與3.7相比,Python 3.8的新功能。有關完整的詳細信息,請參見changelog。
Python 3.8已於2019年10月14日發布。
新功能
賦值表達式
有一種新語法:=
可將值賦給變量,作為較大表達式的一部分。由於它與海象的眼睛和象牙很像,因此被親切地稱為“海象操作員” 。
在此示例中,賦值表達式有助於避免調用 len()
兩次:
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
在正則表達式匹配期間會產生類似的好處,其中需要兩次匹配對象,一次是測試是否發生匹配,另一次是提取子組:
discount = 0.0
if (mo := re.search(r'(\d+)% discount', advertisement)):
discount = float(mo.group(1)) / 100.0
該運算符對while循環也很有用,該循環計算一個值以測試循環終止,然后在循環體中再次需要相同的值:
# Loop over fixed length blocks
while (block := f.read(256)) != '':
process(block)
另一個具有啟發性的用例出現在列表理解中,其中表達式主體中還需要在過濾條件下計算出的值:
[clean_name.title() for name in names
if (clean_name := normalize('NFC', name)) in allowed_names]
請盡量將海象運算符的使用限制在清晰的場合中,以降低復雜性並提升可讀性。
看到 有關完整說明,請參見PEP 572。
僅限位置形參
新增了一個函數形參語法 /
用來指明某些函數形參必須使用僅限位置而非關鍵字參數的形式。 這種標記語法與通過 help()
所顯示的使用 Larry Hastings 的 Argument Clinic 工具標記的 C 函數相同。
在下面的例子中,形參 a 和 b 為僅限位置形參,c 或 d 可以是位置形參或關鍵字形參,而 e 或 f 要求為關鍵字形參:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
以下均為合法的調用:
f(10, 20, 30, d=40, e=50, f=60)
但是,以下均為不合法的調用:
f(10, b=20, c=30, d=40, e=50, f=60) # b cannot be a keyword argument
f(10, 20, 30, 40, 50, f=60) # e must be a keyword argument
這種標記形式的一個用例是它允許純 Python 函數完整模擬現有的用 C 代碼編寫的函數的行為。 例如,內置的 pow()
函數不接受關鍵字參數:
def pow(x, y, z=None, /):
"Emulate the built in pow() function"
r = x ** y
return r if z is None else r%z
另一個用例是在不需要形參名稱時排除關鍵字參數。 例如,內置的 len()
函數的簽名為 len(obj, /)
。 這可以排除如下這種笨拙的調用形式:
len(obj='hello') # The "obj" keyword argument impairs readability
另一個益處是將形參標記為僅限位置形參將允許在未來修改形參名而不會破壞客戶的代碼。 例如,在 statistics
模塊中,形參名 dist 在未來可能被修改。 這使得以下函數描述成為可能:
def quantiles(dist, /, *, n=4, method='exclusive')
...
由於在 /
左側的形參不會被公開為可用關鍵字,其他形參名仍可在 **kwargs
中使用:
>>> def f(a, b, /, **kwargs):
... print(a, b, kwargs)
...
>>> f(10, 20, a=1, b=2, c=3) # a and b are used in two ways
10 20 {'a': 1, 'b': 2, 'c': 3}
這極大地簡化了需要接受任意關鍵字參數的函數和方法的實現。 例如,以下是一段摘自 collections
模塊的代碼:
class Counter(dict):
def __init__(self, iterable=None, /, **kwds):
# Note "iterable" is a possible keyword argument
請參閱 PEP 570 了解詳情。
用於已編譯字節碼文件的並行文件系統緩存
新增的 PYTHONPYCACHEPREFIX
設置 (也可使用 -X
pycache_prefix
) 可將隱式的字節碼緩存配置為使用單獨的並行文件系統樹,而不是默認的每個源代碼目錄下的 __pycache__
子目錄。
緩存的位置會在 sys.pycache_prefix
中報告 (None
表示默認位置即 __pycache__
子目錄)。
調試構建使用與發布構建相同的 ABI
Python 現在不論是以發布模式還是調試模式進行構建都將使用相同的 ABI。 在 Unix 上,當 Python 以調試模式構建時,現在將可以加載以發布模式構建的 C 擴展和使用穩定版 ABI 構建的 C 擴展。
發布構建和調試構建現在都是 ABI 兼容的:定義 Py_DEBUG
宏不會再啟用 Py_TRACE_REFS
宏,它引入了唯一的 ABI 不兼容性。 Py_TRACE_REFS
宏添加了 sys.getobjects()
函數和 PYTHONDUMPREFS
環境變量,它可以使用新的 ./configure --with-trace-refs
構建選項來設置。 (由 Victor Stinner 在 bpo-36465 中貢獻。)
在 Unix 上,C 擴展不會再被鏈接到 libpython,但 Android 和 Cygwin 例外。 現在靜態鏈接的 Python 將可以加載使用共享庫 Python 構建的 C 擴展。 (由 Victor Stinner 在 bpo-21536 中貢獻。)
在 Unix 上,當 Python 以調試模式構建時,導入操作現在也會查找在發布模式下編譯的 C 擴展以及使用穩定版 ABI 編譯的 C 擴展。 (由 Victor Stinner 在 bpo-36722 中貢獻。)
要將 Python 嵌入到一個應用中,必須將新增的 --embed
選項傳給 python3-config --libs --embed
以獲得 -lpython3.8
(將應用鏈接到 libpython)。 要同時支持 3.8 和舊版本,請先嘗試 python3-config --libs --embed
並在此命令失敗時回退到 python3-config --libs
(即不帶 --embed
)。
增加一個 pkg-config python-3.8-embed
模塊用來將 Python 嵌入到一個應用中: pkg-config python-3.8-embed --libs
包含 -lpython3.8
。 要同時支持 3.8 和舊版本,請先嘗試 pkg-config python-X.Y-embed --libs
並在此命令失敗時回退到 pkg-config python-X.Y --libs
(即不帶 --embed
) (請將 X.Y
替換為 Python 版本號)。
另一方面,pkg-config python3.8 --libs
不再包含 -lpython3.8
。 C 擴展不可被鏈接到 libpython
f-字符串支持 =
用於自動記錄表達式和調試文檔
增加 =
說明符用於 f-string。 形式為 f'{expr=}'
的 f-字符串將擴展表示為表達式文本,加一個等於號,再加表達式的求值結果。 例如:
>>> user = 'eric_idle'
>>> member_since = date(1975, 7, 31)
>>> f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"
通常的 f-字符串格式說明符 允許更細致地控制所要顯示的表達式結果:
>>> delta = date.today() - member_since
>>> f'{user=!s} {delta.days=:,d}'
'user=eric_idle delta.days=16,075'
=
說明符將輸出整個表達式,以便詳細演示計算過程:
>>> print(f'{theta=} {cos(radians(theta))=:.3f}')
theta=30 cos(radians(theta))=0.866
新增模塊
新增的 importlib.metadata
模塊提供了從第三方包讀取元數據的(臨時)支持。 例如,它可以提取一個已安裝軟件包的版本號、入口點列表等等:
>>> # Note following example requires that the popular "requests"
>>> # package has been installed.
>>>
>>> from importlib.metadata import version, requires, files
>>> version('requests')
'2.22.0'
>>> list(requires('requests'))
['chardet (<3.1.0,>=3.0.2)']
>>> list(files('requests'))[:5]
[PackagePath('requests-2.22.0.dist-info/INSTALLER'),
PackagePath('requests-2.22.0.dist-info/LICENSE'),
PackagePath('requests-2.22.0.dist-info/METADATA'),
PackagePath('requests-2.22.0.dist-info/RECORD'),
PackagePath('requests-2.22.0.dist-info/WHEEL')]
改進的模塊
ast
AST 節點現在具有 end_lineno
和 end_col_offset
屬性,它們給出節點結束的精確位置。 (這只適用於具有 lineno
和 col_offset
屬性的節點。)
新增函數 ast.get_source_segment()
返回指定 AST 節點的源代碼。
ast.parse()
函數具有一些新的旗標:
type_comments=True
導致其返回與特定 AST 節點相關聯的 PEP 484 和 PEP 526 類型注釋文本;mode='func_type'
可被用於解析 PEP 484 "簽名類型注釋" (為函數定義 AST 節點而返回);feature_version=(3, N)
允許指定一個更早的 Python 3 版本。 (例如,feature_version=(3, 4)
將把async
和await
視為非保留字。)
asyncio
輸入python -m asyncio
將直接發起異步PEPL,這樣就不需要讓特別緊急的任務處於等待狀態,也不需要再輸入asyncio.run()
來直接調用
$ python -m asyncio
asyncio REPL 3.8.0
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> await asyncio.sleep(10, result='hello')
hello
在 Windows 上,現在默認的事件循環為 ProactorEventLoop
。ProactorEventLoop
現在也支持 UDP。 ProactorEventLoop
現在可通過 KeyboardInterrupt
("CTRL+C") 來中斷。
collections
collections.namedtuple()
的 _asdict()
方法現在將返回 dict
而不是 collections.OrderedDict
。 此項更改是因為普通字典自 Python 3.7 起已保證具有確定的元素順序。 如果還需要 OrderedDict
的額外特性,推薦的解決方案是將結果轉換為需要的類型: OrderedDict(nt._asdict())
。
curses
添加了一個新變量用於保存下層 ncurses 庫的結構版信息: ncurses_version
。
datetime
添加了新的替代構造器 datetime.date.fromisocalendar()
和 datetime.datetime.fromisocalendar()
,它們分別基於 ISO 年份、周序號和周內日序號來構造 date
和 datetime
對象;這兩者分別是其所對應類中 isocalendar
方法的逆操作。 (由 Paul Ganssle 在 bpo-36004 中貢獻。)
functools
functools.lru_cache()
現在可直接作為裝飾器而不是作為返回裝飾器的函數。 因此這兩種寫法現在都被支持:
@lru_cache
def f(x):
...
@lru_cache(maxsize=256)
def f(x):
...
添加了一個新的functools.cached_property()裝飾器,用於在實例生命期內緩存的計算屬性。
import functools
import statistics
class Dataset:
def __init__(self, sequence_of_numbers):
self.data = sequence_of_numbers
@functools.cached_property
def variance(self):
return statistics.variance(self.data)
gc
get_objects()現在可以接收一個可選的生成參數,指示從中獲取對象的生成
gettext
添加了 pgettext()
及其變化形式
gzip
添加 mtime 形參到 gzip.compress()
用於可重現的輸出。 (由 Guo Ci Teo 在 bpo-34898 中貢獻。)
對於特定類型的無效或已損壞 gzip 文件現在將引發 BadGzipFile
而不是 OSError
。
idlelib 與 IDLE
超過 N 行(默認值為 50)的輸出將被折疊為一個按鈕。 N 可以在 Settings 對話框的 General 頁的 PyShell 部分中進行修改。 數量較少但是超長的行可以通過在輸出上右擊來折疊。 被折疊的輸出可通過雙擊按鈕來展開,或是通過右擊按鈕來放入剪貼板或是單獨的窗口。
在 Run 菜單中增加了 "Run Customized" 以使用自定義設置來運行模塊。 輸入的任何命令行參數都會被加入 sys.argv。 它們在下次自定義運行時會再次顯示在窗體中。 用戶也可以禁用通常的 Shell 主模塊重啟。
在 IDLE 編輯器窗口中增加了可選的行序號。 窗口打開時默認不帶行序號,除非在配置對話框的 General 選項卡中進行設置。 已打開窗口中的行序號可以在 Options 菜單中顯示和隱藏。
上述修改已被反向移植到 3.7 維護發行版中。
inspect
inspect.getdoc()
函數現在可以找到 __slots__
的文檔字符串,如果該屬性是一個元素值為文檔字符串的 dict
的話。 這提供了類似於目前已有的 property()
, classmethod()
和 staticmethod()
等函數的文檔選項:
class AudioClip:
__slots__ = {'bit_rate': 'expressed in kilohertz to one decimal place',
'duration': 'in seconds, rounded up to an integer'}
def __init__(self, bit_rate, duration):
self.bit_rate = round(bit_rate / 1000.0, 1)
self.duration = ceil(duration)
io
在開發模式 (-X
env
) 和調試構建中,io.IOBase
終結器現在會在 close()
方法失敗時將異常寫入日志。 發生的異常在發布構建中默認會被靜默忽略。
json.tool
添加選項 --json-lines
用於將每個輸入行解析為單獨的 JSON 對象。
math
添加了新的函數 math.dist()
用於計算兩點之間的歐幾里得距離。
擴展了 math.hypot()
函數以便處理更多的維度。 之前它僅支持 2-D 的情況。
添加了新的函數 math.prod()
作為的 sum()
同類,該函數返回 'start' 值 (默認值: 1) 乘以一個數字可迭代對象的積:
>>> prior = 0.8
>>> likelihoods = [0.625, 0.84, 0.30]
>>> math.prod(likelihoods, start=prior)
0.126
添加了新的函數 math.isqrt()
用於計算整數平方根。
函數 math.factorial()
不再接受非整數類參數。
mmap
mmap.mmap
類現在具有一個 madvise()
方法用於訪問 madvise()
系統調用。
multiprocessing
新增 multiprocessing.shared_memory
模塊.
在macOS上,現在默認使用的啟動方式是spawn啟動方式。
os
添加了新的 os.memfd_create()
函數用於包裝 memfd_create()
系統調用。
在 Windows 上,大部分用於處理重解析點,(包括符號鏈接和目錄連接)的手動邏輯已被委托給操作系統。 特別地,os.stat()
現在將會遍歷操作系統所支持的任何內容,而 os.lstat()
將只打開被標識為“名稱代理”的重解析點,而其要由 os.stat()
打開其他的重解析點。 在所有情況下,stat_result.st_mode
將只為符號鏈接而非其他種類的重解析點設置 S_IFLNK
。 要標識其他種類的重解析點,請檢查新的 stat_result.st_reparse_tag
屬性。
在 Windows 上,os.readlink()
現在能夠讀取目錄連接。 請注意 islink()
會對目錄連接返回 False
,因此首先檢查 islink
的代碼將連續把連接視為目錄,而會處理 os.readlink()
所引發錯誤的代碼現在會把連接視為鏈接。
os.path
返回布爾值結果的 os.path
函數例如 exists()
, lexists()
, isdir()
, isfile()
, islink()
, 以及 ismount()
現在對於包含在 OS 層級無法表示的字符或字節的路徑將會返回 False
而不是引發 ValueError
或其子類 UnicodeEncodeError
和 UnicodeDecodeError
。
expanduser()
on Windows now prefers the USERPROFILE
environment variable and does not use HOME
, which is not normally set for regular user accounts.
isdir()
在 Windows 上不再為不存在的目錄的鏈接返回真值。
realpath()
在 Windows 上現在會識別重解析點,包括符號鏈接和目錄連接。
pathlib
返回布爾值結果的 pathlib.Path
方法例如 exists()
, is_dir()
, is_file()
, is_mount()
, is_symlink()
, is_block_device()
, is_char_device()
, is_fifo()
, is_socket()
現在對於包含在 OS 層級無法表示的字符或字節的路徑將會返回 False
而不是引發 ValueError
或其子類 UnicodeEncodeError
。
添加了 pathlib.Path.link_to()
用於創建指向某個路徑的硬鏈接。
plistlib
添加了新的 plistlib.UID
並啟動了對讀取和寫入經過 NSKeyedArchiver 編碼的二進制 plists 的支持
py_compile
py_compile.compile()
現在支持靜默模式。
shlex
新增了 shlex.join()
函數作為 shlex.split()
的逆操作。
shutil
shutil.copytree()
現在接受新的 dirs_exist_ok
關鍵字參數。
shutil.make_archive()
現在對新的歸檔默認使用 modern pax (POSIX.1-2001) 格式以提升可移植性和標准一致性,此特性繼承自對 tarfile
模塊的相應更改。
shutil.rmtree()
on Windows now removes directory junctions without recursively removing their contents first.
socket
添加了便捷的 create_server()
和 has_dualstack_ipv6()
函數以自動化在創建服務器套接字時通常情況下所必須的任務,包括在同一套接字中同時接受 IPv4 和 IPv6 連接。
socket.if_nameindex()
, socket.if_nametoindex()
和 socket.if_indextoname()
函數已經在 Windows 上實現。
ssl
增加了 ssl.SSLContext.post_handshake_auth
以及 ssl.SSLSocket.verify_client_post_handshake()
來啟用並初始化 TLS 1.3 握手后驗證。
statistics
添加了 statistics.fmean()
作為 statistics.mean()
的更快速的浮點數版版本。
添加了 statistics.geometric_mean()
添加了 statistics.multimode()
用於返回最常見值的列表。
添加了 statistics.quantiles()
用於將數據或分布划分為多個等概率區間
添加了 statistics.NormalDist
用於創建和操縱隨機變量的正態分布。
>>> temperature_feb = NormalDist.from_samples([4, 12, -3, 2, 7, 14])
>>> temperature_feb.mean
6.0
>>> temperature_feb.stdev
6.356099432828281
>>> temperature_feb.cdf(3) # Chance of being under 3 degrees
0.3184678262814532
>>> # Relative chance of being 7 degrees versus 10 degrees
>>> temperature_feb.pdf(7) / temperature_feb.pdf(10)
1.2039930378537762
>>> el_niño = NormalDist(4, 2.5)
>>> temperature_feb += el_niño # Add in a climate effect
>>> temperature_feb
NormalDist(mu=10.0, sigma=6.830080526611674)
>>> temperature_feb * (9/5) + 32 # Convert to Fahrenheit
NormalDist(mu=50.0, sigma=12.294144947901014)
>>> temperature_feb.samples(3) # Generate random samples
[7.672102882379219, 12.000027119750287, 4.647488369766392]
sys
添加了新的 sys.unraisablehook()
函數,可被重載以便控制如何處理“不可引發的異常”。 它會在發生了一個異常但 Python 沒有辦法處理時被調用。 例如,當一個析構器在垃圾回收時 (gc.collect()
) 所引發的異常。
tarfile
tarfile
模塊現在對新的歸檔默認使用 modern pax (POSIX.1-2001) 格式而不再是之前的 GNU 專屬格式。 這通過標准化和可擴展格式的統一編碼 (UTF-8) 提升了跨平台可移植性,還提供了其他一些益處。
threading
添加了新的 threading.excepthook()
函數用來處理未捕獲的 threading.Thread.run()
異常。 它可被重載以便控制如何處理未捕獲的 threading.Thread.run()
異常。
添加了新的 threading.get_native_id()
函數以及 threading.Thread
類的 native_id
屬性。 它們會返回內核所分配給當前線程的原生整數線程 ID。 此特性僅在特定平台上可用,參見 get_native_id
了解詳情。
tokenize
當提供不帶末尾新行的輸入時,tokenize
模塊現在會隱式地添加 NEWLINE
形符。 此行為現在已與 C 詞法分析器的內部行為相匹配。
tkinter
在 tkinter.Spinbox
中添加了方法 selection_from()
, selection_present()
, selection_range()
和 selection_to()
。
在 tkinter.Canvas
類中添加了方法 moveto()
。
tkinter.PhotoImage
類現在具有 transparency_get()
和 transparency_set()
方法。
time
為 macOS 10.12 添加了新的時鍾 CLOCK_UPTIME_RAW
。
typing
typing
模塊加入了一些新特性:
-
一個帶有鍵專屬類型的字典類型。 參見 PEP 589 和
typing.TypedDict
。 TypedDict 只使用字符串作為鍵。 默認情況下每個鍵都要求提供。 指定 "total=False" 以允許鍵作為可選項:class Location(TypedDict, total=False): lat_long: tuple grid_square: str xy_coordinate: tuple
-
Literal 類型。 參見 PEP 586 和
typing.Literal
。 Literal 類型指明一個形參或返回值被限定為一個或多個特定的字面值:def get_status(port: int) -> Literal['connected', 'disconnected']: ...
-
"Final" 變量、函數、方法和類。 參見 PEP 591,
typing.Final
和typing.final()
。 final 限定符會指示靜態類型檢查器限制進行子類化、重載或重新賦值:pi: Final[float] = 3.1415926536
-
協議定義。 參見 PEP 544,
typing.Protocol
和typing.runtime_checkable()
。 簡單的 ABC 例如typing.SupportsInt
現在是Protocol
的子類。 -
新的協議類
typing.SupportsIndex
。 -
新的函數
typing.get_origin()
和typing.get_args()
。
unicodedata
unicodedata
模塊現在已升級為使用 Unicode 12.1.0 發布版。
新的函數 is_normalized()
可被用來驗證字符串是否為特定正規形式,通常會比實際進行字符串正規化要快得多。
unittest
添加了 AsyncMock
以支持異步版本的 Mock
。 同時也添加了相應的斷言函數用於測試。
unittest 添加了 addModuleCleanup()
和 addClassCleanup()
以支持對 setUpModule()
和 setUpClass()
進行清理。
一些模擬斷言函數現在也會在失敗時打印一個實際調用列表。
unittest
模塊已支持通過 unittest.IsolatedAsyncioTestCase
來使用協程作為測試用例。
import unittest
class TestRequest(unittest.IsolatedAsyncioTestCase):
async def asyncSetUp(self):
self.connection = await AsyncConnection()
async def test_get(self):
response = await self.connection.get("https://example.com")
self.assertEqual(response.status_code, 200)
async def asyncTearDown(self):
await self.connection.close()
if __name__ == "__main__":
unittest.main()
venv
現在 venv
在所有平台上都會包含 Activate.ps1
腳本用於在 PowerShell Core 6.1 下激活虛擬環境。
weakref
由 weakref.proxy()
返回的代理對象現在除其他算術運算符外也支持矩陣乘法運算符 @
和 @=
。
xml
作為對 DTD 和外部實體檢索的緩解,在默認情況下 xml.dom.minidom
和 xml.sax
模塊不再處理外部實體。
xml.etree.ElementTree
模塊中的 .find*()
方法支持通配符搜索例如 {*}tag
,此搜索會忽略命名空間以及返回給定命名空間中所有標簽的 {namespace}*
。
xml.etree.ElementTree
模塊提供了實現 C14N 2.0 的新函數 –xml.etree.ElementTree.canonicalize()
。
xml.etree.ElementTree.XMLParser
的目標對象可通過新的回調方法 start_ns()
和 end_ns()
來接受命名空間聲明事件。 此外,xml.etree.ElementTree.TreeBuilder
目標可被配置為處理有關注釋和處理指令事件以將它們包含在所生成的樹當中。
性能優化
-
subprocess
模塊現在能在某些情況下使用os.posix_spawn()
函數以獲得更好的性能。 目前,它的使用僅限 macOS 和 Linux(使用 glibc 2.24 或更新版本),並要求滿足以下條件:- close_fds 為假值;
- preexec_fn, pass_fds, cwd 和 start_new_session 形參未設置;
- executable 路徑包含一個目錄。
(由 Joannah Nanjekye 和 Victor Stinner 在 bpo-35537 中貢獻。)
-
shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
和shutil.move()
在 Linux 和 macOS 上會使用平台專屬的 "fast-copy" 系統調用以提高效率。 "fast-copy" 意味着拷貝操作發生於內核中,從而避免在進行 "outfd.write(infd.read())
" 等操作時使用 Python 中的用戶空間緩沖區。 在 Windows 上shutil.copyfile()
會使用更大的默認緩沖區(1 MiB 而不是 16 KiB)並且使用基於memoryview()
的shutil.copyfileobj()
版本。 在同一分區內拷貝一個 512 MiB 文件的速度提升在 Linux 上約為 +26%,在 macOS 上為 +50%,在 Windows 上為 +40%。 此外還將消耗更少的 CPU 周期。 參見 Platform-dependent efficient copy operations 一節。 (由 Giampaolo Rodolà 在 bpo-33671 中貢獻。) -
shutil.copytree()
會根據其所用緩存的os.stat()
值使用os.scandir()
函數及所有拷貝函數。 拷貝一個包含 8000 文件的目錄的速度提升在 Linux 上約為 +9%,在 Windows 上為 +20%,對於 Windows SMB 共享目錄則為 +30%。 此外os.stat()
系統調用的次數也減少了 38%,使得shutil.copytree()
在網絡文件系統上會特別快速。 (由Giampaolo Rodolà 在 bpo-33695 中貢獻。) -
pickle
模塊使用的默認協議現在為 Protocol 4,最早在 Python 3.4 中被引入。 它提供了比自 Python 3.0 起可用的 Protocol 3 更好的性能和更小的數據尺寸。 -
Removed one
Py_ssize_t
member fromPyGC_Head
. All GC tracked objects (e.g. tuple, list, dict) size is reduced 4 or 8 bytes. (Contributed by Inada Naoki in bpo-33597.) -
uuid.UUID
now uses__slots__
to reduce its memory footprint. (Contributed by Wouter Bolsterlee and Tal Einat in bpo-30977) -
operator.itemgetter()
的性能提升了 33%。 優化了參數處理,並為常見的在元組中單個非負整數索引的情況新增了一條快速路徑(這是標准庫中的典型用例)。 (由 Raymond Hettinger 在 bpo-35664 中貢獻。 -
加快了在
collections.namedtuple()
中的字段查找。 它們現在的速度快了兩倍以上,成為 Python 中最快的實例變量查找形式。 (由 Raymond Hettinger, Pablo Galindo 和 Joe Jevnik, Serhiy Storchaka 在 bpo-32492 中貢獻。) -
如果輸入的可迭代對象的長度已知 (即輸入對象實現了
__len__
),list
構造器不會過度分配內部項緩沖區。 這使得所創建的列表資源占用平均減少了 12%。 (由 Raymond Hettinger 和 Pablo Galindo 在 bpo-33234 中貢獻。) -
類變量寫入速度加倍。 當一個非冗余屬性被更新時,之前存在一個更新 slots 的非必要調用。 (由 Stefan Behnel, Pablo Galindo Salgado, Raymond Hettinger, Neil Schemenauer, 和 Serhiy Storchaka 在 bpo-36012 中貢獻。)
-
減少了傳遞給許多內置函數和方法的參數轉換的開銷。 這使得某些簡單內置函數和方法的速度提升了 20--50%。 (由 Serhiy Storchaka 在 bpo-23867, bpo-35582 和 bpo-36127 中貢獻。)
-
LOAD_GLOBAL
指令現在會使用新的 "per opcode cache" 機制。 它的速度現在提升了大約 40%。 (由 Yury Selivanov 和 Inada Naoki 在 bpo-26219 中貢獻。)
構建和 C API 的改變
-
默認的
sys.abiflags
成為一個空字符串:pymalloc 的m
旗標不再有意義(無論是否啟用 pymalloc 構建都是兼容 ABI 的)因此已被移除。 (由 Victor Stinner 在 bpo-36707 中貢獻。)改變的例子:
- 只會安裝
python3.8
程序,不再有python3.8m
程序。 - 只會安裝
python3.8-config
腳本,不再有python3.8m-config
腳本。 m
旗標已經從動態庫文件名后綴中移除:包括標准庫中的擴展模塊以及第三方包所產生和安裝的模塊例如從 PyPI 下載的模塊。 以 Linux 為例,Python 3.7 的后綴.cpython-37m-x86_64-linux-gnu.so
在 Python 3.8 中改為.cpython-38-x86_64-linux-gnu.so
。
- 只會安裝
-
重新組織了所有頭文件以更好地區分不同種類的 API:
Include/*.h
應為可移植的公有穩定版 C API。Include/cpython/*.h
應為 CPython 專屬的不穩定版 C API;公有 API,部分私有 API 附加_Py
or_PY
前綴。Include/internal/*.h
應為 CPython 特別專屬的私有內部 C API。 此 API 不具備向下兼容保證並且不應在 CPython 以外被使用。 它們的公開僅適用於特別限定的需求例如調試器和性能分析等必須直接訪問 CPython 內部數據而不通過調用函數的應用。 此 API 現在是通過make install
安裝的。
(由 Victor Stinner 在 bpo-35134 和 bpo-35081 中貢獻,相關工作由 Eric Snow 在 Python 3.7 中發起。)
-
某些宏已被轉換為靜態內聯函數:形參類型和返回類型定義良好,它們不再會有與宏相關的問題,變量具有局部作用域。 例如:
Py_INCREF()
,Py_DECREF()
Py_XINCREF()
,Py_XDECREF()
PyObject_INIT()
,PyObject_INIT_VAR()
- 私有函數:
_PyObject_GC_TRACK()
,_PyObject_GC_UNTRACK()
,_Py_Dealloc()
(由 Victor Stinner 在 bpo-35059 中貢獻。)
-
PyByteArray_Init()
和PyByteArray_Fini()
函數已被移除。 它們自 Python 2.7.4 和 Python 3.2.0 起就沒有任何用處,被排除在受限 API (穩定版 ABI) 之外,並且未被寫入文檔。 (由 Victor Stinner 在 bpo-35713 中貢獻。) -
PyExceptionClass_Name()
的結果類型現在是const char *
而非char *
。 (由 Serhiy Storchaka 在 bpo-33818 中貢獻。) -
Modules/Setup.dist
與Modules/Setup
兩者的共存已被移除。 之前在更新 CPython 源碼樹時,開發者必須手動拷貝Modules/Setup.dist
(在源碼樹內) 到Modules/Setup
(在構建樹內) 以反映上游的任何改變。 舊特性對打包者來說有一點益處,但代價是對追蹤 CPython 開發進程的開發者造成經常性的麻煩,因為忘記拷貝該文件可能導致構建失敗。現在構建系統總是會從源碼樹內的
Modules/Setup
讀取數據。 建議希望定制該文件的開發者在 CPython 的一個 git 分叉或補丁文件中維護他們的更改,就如他們對源碼樹做任何其他改變時一樣。(由 Antoine Pitrou 在 bpo-32430 中貢獻。)
-
將 Python 數字轉換為 C 整型的函數例如
PyLong_AsLong()
以及帶有'i'
之類整型轉換格式單元的參數解析函數例如PyArg_ParseTuple()
現在如果可能將會使用__index__()
特殊方法而不是__int__()
。 對於帶有__int__()
方法但沒有__index__()
方法的對象 (例如Decimal
和Fraction
) 將會發出棄用警告。 對於實現了__index__()
的對象PyNumber_Check()
現在將返回1
。PyNumber_Long()
,PyNumber_Float()
和PyFloat_AsDouble()
現在如果可能也將會使用__index__()
方法。 (由 Serhiy Storchaka 在 bpo-36048 和 bpo-20092 中貢獻。) -
堆分配類型對象現在將增加它們在
PyObject_Init()
(及其對應的宏PyObject_INIT
) 中的引用計數而不是在PyType_GenericAlloc()
中。 修改實例分配或中止分配的類型可能需要進行調整。 (由 Elizondo 在 bpo-35810 中貢獻。) -
新增函數
PyCode_NewWithPosOnlyArgs()
允許創建代碼對象例如PyCode_New()
,但帶有一個額外的 posonlyargcount 形參以指明僅限位置參數的數量。 (由 Pablo Galindo 在 bpo-37221 中貢獻。) -
Py_SetPath()
現在會將sys.executable
設為程序完整路徑 (Py_GetProgramFullPath()
) 而不是程序名稱 (Py_GetProgramName()
)。 (由 Victor Stinner 在 bpo-38234 中貢獻。)
棄用
-
distutils 的
bdist_wininst
命令現在已棄用,請改用bdist_wheel
(wheel 包)。 (由 Victor Stinner 在 bpo-37481 中貢獻。) -
ElementTree
模塊中的已棄用方法getchildren()
和getiterator()
現在會引發DeprecationWarning
而不是PendingDeprecationWarning
。 它們將在 Python 3.9 中被移除。 (由 Serhiy Storchaka 在 bpo-29209 中貢獻。) -
將不是
concurrent.futures.ThreadPoolExecutor
實例的對象傳給asyncio.loop.set_default_executor()
已被棄用,並將在 Python 3.9 中被禁止。 (由 Elvis Pranskevichus 在 bpo-34075 中貢獻。) -
xml.dom.pulldom.DOMEventStream
,wsgiref.util.FileWrapper
和fileinput.FileInput
的__getitem__()
方法已被棄用。這些方法的實現會忽略它們的 index 形參,並改為返回下一條目。 (由 Berker Peksag 在 bpo-9372 中貢獻。)
-
typing.NamedTuple
類已棄用了_field_types
屬性而改用具有同樣信息的__annotations__
屬性。 (由 Raymond Hettinger 在 bpo-36320 中貢獻。) -
ast
類Num
,Str
,Bytes
,NameConstant
和Ellipsis
被視為已棄用並將在未來的 Python 版本中被移除。 應當改用Constant
。 (由 Serhiy Storchaka 在 bpo-32892 中貢獻。) -
ast.NodeVisitor
的方法visit_Num()
,visit_Str()
,visit_Bytes()
,visit_NameConstant()
和visit_Ellipsis()
現在已被棄用,並且在未來的 Python 版本中將不再被調用。 添加visit_Constant()
方法來處理所有常量節點。 (由 Serhiy Storchaka 在 bpo-36917 中貢獻。) -
gettext
模塊中的下列函數和方法已被棄用:lgettext()
,ldgettext()
,lngettext()
和ldngettext()
。 它們返回已編碼的字節串,如果轉換后的字符串存在編碼問題你將可能遭遇預期之外的異常。 更好的做法是使用 Python 3 中返回 Unicode 字符串的操作作為替代。 前面的函數都早已不宜使用。函數
bind_textdomain_codeset()
,方法output_charset()
和set_output_charset()
,以及函數translation()
和install()
的 codeset 形參也憶被棄用,因為它們僅適用於l*gettext()
函數。 (由 Serhiy Storchaka 在 bpo-33710 中貢獻。) -
threading.Thread
的isAlive()
方法已棄用。 (由 Dong-hee Na 在 bpo-35283 中貢獻。) -
許多接受整數參數的內置和擴展模塊的函數現在將對傳入
Decimal
,Fraction
以及任何其他可被轉換為整數但會丟失精度(即具有__int__()
方法但沒有__index__()
方法)的對象發出棄用警告。 在未來的版本中則將報錯。 (由 Serhiy Storchaka 在 bpo-36048 中貢獻。) -
以下參數作為關鍵字參數傳遞的方式已被棄用:
functools.partialmethod()
,weakref.finalize()
,profile.Profile.runcall()
,cProfile.Profile.runcall()
,bdb.Bdb.runcall()
,trace.Trace.runfunc()
與curses.wrapper()
中的 func。unittest.TestCase.addCleanup()
中的 function。concurrent.futures.ThreadPoolExecutor
和concurrent.futures.ProcessPoolExecutor
的submit()
方法中的 fn。contextlib.ExitStack.callback()
,contextlib.AsyncExitStack.callback()
和contextlib.AsyncExitStack.push_async_callback()
中的 callback。multiprocessing.managers.Server
和multiprocessing.managers.SharedMemoryServer
的create()
方法中的 c 和 typeid。weakref.finalize()
中的 obj。
在未來版本的 Python 中它們將成為 僅限位置參數。 (由 Serhiy Storchaka 在 bpo-36492 中貢獻。)
API 與特性的移除
下列特性與 API 已從 Python 3.8 中移除:
macpath
模塊,在 Python 3.7 中棄用,現已被移除。- 函數
platform.popen()
已被移除,它自 Python 3.3 起就已被棄用:請改用os.popen()
。 - 函數
time.clock()
已被移除,它自 Python 3.3 起就已被棄用:請根據具體需求改用time.perf_counter()
或time.process_time()
以獲得具有良好定義的行為。 pyvenv
腳本已被移除,推薦改用python3.8 -m venv
來幫助消除容易混淆pyvenv
腳本所關聯的 Python 解釋器這一問題。parse_qs
,parse_qsl
和escape
已從cgi
模塊中被移除。 這些函數自 Python 3.2 或更早就已被棄用。 它們應改為從urllib.parse
和html
模塊導入。filemode
函數已從tarfile
模塊中被移除。 該函數未被寫入文檔,自 Python 3.3 起就已棄用。XMLParser
構造器不再接受 html 參數。 它從來沒有任何作用並在 Python 3.4 中已被棄用。 所有其他形參現在都是 僅限關鍵字參數。XMLParser
的doctype()
方法已被移除。- "unicode_internal" 編解碼器已被移除。
sqlite3
模塊的Cache
和Statement
對象已不再公開給用戶。fileinput.input()
和fileinput.FileInput()
中自 Python 3.6 起就已被忽略並棄用的bufsize
關鍵字參數已被移除。- 在 Python 3.7 中棄用的函數
sys.set_coroutine_wrapper()
和sys.get_coroutine_wrapper()
已被移除。
移植到 Python 3.8
本節列出了先前描述的更改以及可能需要更改代碼的其他錯誤修正.
Python 行為的改變
- yield 表達式(包括
yield
和yield from
子句)現在不允許在推導式和生成器表達式中使用(但for
子句最左邊的可迭代對象表達式除外)。 (由 Serhiy Storchaka 在 bpo-10544 中貢獻。) - The compiler now produces a
SyntaxWarning
when identity checks (is
andis not
) are used with certain types of literals (e.g. strings, numbers). These can often work by accident in CPython, but are not guaranteed by the language spec. The warning advises users to use equality tests (==
and!=
) instead. (Contributed by Serhiy Storchaka in bpo-34850.) - CPython 解釋器在某些情況下可以忽略異常。 在 Python 3.8 中這種情況會更少發生。 特別地,從類型字典獲取屬性時引發的異常不會再被忽略。 (由 Serhiy Storchaka 在 bpo-35459 中貢獻。)
- 從內置類型
bool
,int
,float
,complex
和標准庫的一些類中移除了__str__
實現。 它們現在會從object
繼承__str__()
。 作為結果,在這些類的子類中定義__repr__()
方法將會影響它們的字符串表示。 (由 Serhiy Storchaka 在 bpo-36793 中貢獻。) - 在 AIX 上,
sys.platform
將不再包含主要版本號。 它將總是'aix'
而不再是'aix3'
..'aix7'
。 由於較舊的 Python 版本會包含該版本號,因此推薦總是使用sys.platform.startswith('aix')
。 (由 M. Felt 在 bpo-36588 中貢獻。) PyEval_AcquireLock()
andPyEval_AcquireThread()
now terminate the current thread if called while the interpreter is finalizing, making them consistent withPyEval_RestoreThread()
,Py_END_ALLOW_THREADS()
, andPyGILState_Ensure()
. If this behavior is not desired, guard the call by checking_Py_IsFinalizing()
orsys.is_finalizing()
. (Contributed by Joannah Nanjekye in bpo-36475.)
更改的Python API
- 在 Windows 上
os.getcwdb()
函數現在會使用 UTF-8 編碼格式而不是 ANSI 代碼頁:請參看 PEP 529 了解具體原因。 該函數在 Windows 上不再被棄用。 (由 Victor Stinner 在 bpo-37412 中貢獻。) - 現在
subprocess.Popen
在某些情況下會使用os.posix_spawn()
以獲得更好的性能。 在適用於 Linux 的 Windows 子系統和 QEMU 用戶模擬器上,使用os.posix_spawn()
的Popen
構造器不會再因為“找不到程序”這樣的錯誤引發異常。 而是讓子進程失敗並返回一個非零的returncode
。 (由 Joannah Nanjekye 和 Victor Stinner 在 bpo-35537 中貢獻。) - The preexec_fn argument of *
subprocess.Popen
is no longer compatible with subinterpreters. The use of the parameter in a subinterpreter now raisesRuntimeError
. (Contributed by Eric Snow in bpo-34651, modified by Christian Heimes in bpo-37951.) - The
imap.IMAP4.logout()
method no longer ignores silently arbitrary exceptions. (Contributed by Victor Stinner in bpo-36348.) - 函數
platform.popen()
已被移除,它自 Python 3.3 起就已被棄用:請改用os.popen()
。 (由 Victor Stinner 在 bpo-35345 中貢獻。) - 當傳入多模數據時
statistics.mode()
函數不會再引發異常。 它將改為返回在輸入數據中遇到的第一個模式。 (由 Raymond Hettinger 在 bpo-35892 中貢獻。) tkinter.ttk.Treeview
類的selection()
方法不再接受參數。 帶參數調用該方法來改變選擇在 Python 3.6 中已棄用。 請使用專門方法例如selection_set()
來改變選擇。 (由 Serhiy Storchaka 在 bpo-31508 中貢獻。)xml.dom.minidom
的writexml()
,toxml()
和toprettyxml()
方法以及xml.etree
的write()
方法現在會保留用戶指定的屬性順序。 (由 Diego Rojas 和 Raymond Hettinger 在 bpo-34160 中貢獻。)- 附帶
'r'
旗標打開的dbm.dumb
數據庫現在將是只讀的。 如果數據庫不存在,附帶'r'
和'w'
旗標的dbm.dumb.open()
不會再創建數據庫。 (由 Serhiy Storchaka 在 bpo-32749 中貢獻。) - 在
XMLParser
的子類中定義的doctype()
方法將不會再被調用,並將導致發出RuntimeWarning
而不是DeprecationWarning
。 請在目標上定義doctype()
方法來處理 XML doctype 聲明。 (由 Serhiy Storchaka 在 bpo-29209 中貢獻。) - 現在當自定義元類未在傳給
type.__new__
的命名空間中提供__classcell__
入口時將引發RuntimeError
。 在 Python 3.6--3.7 中是則是引發DeprecationWarning
。 (由 Serhiy Storchaka 在 bpo-23722 中貢獻。) cProfile.Profile
類現在可被用作上下文管理器。 (由 Scott Sanderson 在 bpo-29235 中貢獻。)shutil.copyfile()
,shutil.copy()
,shutil.copy2()
,shutil.copytree()
和shutil.move()
會使用平台專屬的 "fast-copy" 系統調用(參見 Platform-dependent efficient copy operations 一節)。shutil.copyfile()
在 Windows 上的默認緩沖區大小從 16 KiB 改為 1 MiB。PyGC_Head
結構已被完全改變。 所有接觸到該結構的代碼都應當被重寫。 (參見 bpo-33597。)PyInterpreterState
結構已被移入 "internal" 頭文件 (特別是 Include/internal/pycore_pystate.h)。 不透明的PyInterpreterState
作為公有 API (和穩定版 ABI) 的一部分仍然可用。 文檔指明該結構的任何字段都不是公有的,因此我們希望沒人在使用它們。 但是,如果你確實依賴其中某一個或更多個私有字段並且沒有其他替代選項,則請開一個 BPO 問題。 我們將盡力幫助你進行調整 (可能包括向公有 API 添加訪問器函數)。 (參見 bpo-35886。)- 現在 asyncio 任務可以被命名,具體方式是將
name
關鍵字參數傳給asyncio.create_task()
或create_task()
事件循環方法,或是在任務對象上調用set_name()
方法。 任務名稱可在asyncio.Task
的repr()
輸出中查看,並可使用get_name()
方法來獲取。 - 現在所有平台下的
mmap.flush()
方法都會在成功時返回None
並在錯誤時引發異常。 之前它的行為取決於具體平台: Windows 下會在成功時返回非零值;在失敗時返回零。 Unix 下會在成功時返回零;在失敗時引發錯誤。 (由 Berker Peksag 在 bpo-2122 中貢獻。) xml.dom.minidom
和xml.sax
模塊默認將不再處理外部實體。 (由 Christian Heimes 在 bpo-17239 中貢獻。)- 從只讀的
dbm
數據庫 (dbm.dumb
,dbm.gnu
或dbm.ndbm
) 刪除鍵將會引發error
(dbm.dumb.error
,dbm.gnu.error
或dbm.ndbm.error
) 而不是KeyError
。 (由 Xiang Zhang 在 bpo-33106 中貢獻。) expanduser()
on Windows now prefers theUSERPROFILE
environment variable and does not useHOME
, which is not normally set for regular user accounts. (Contributed by Anthony Sottile in bpo-36264.)- The exception
asyncio.CancelledError
now inherits fromBaseException
rather than aException
. (Contributed by Yury Selivanov in bpo-13528.) - DLL dependencies for extension modules and DLLs loaded with
ctypes
on Windows are now resolved more securely. Only the system paths, the directory containing the DLL or PYD file, and directories added withadd_dll_directory()
are searched for load-time dependencies. Specifically,PATH
and the current working directory are no longer used, and modifications to these will no longer have any effect on normal DLL resolution. If your application relies on these mechanisms, you should check foradd_dll_directory()
and if it exists, use it to add your DLLs directory while loading your library. Note that Windows 7 users will need to ensure that Windows Update KB2533625 has been installed (this is also verified by the installer). (Contributed by Steve Dower in bpo-36085.) - 關聯到 pgen 的頭文件和函數在其被純 Python 實現取代后已被移除。 (由 Pablo Galindo 在 bpo-36623 中貢獻。)
types.CodeType
在構造器的第二個位置新增了一個形參 (posonlyargcount) 以支持在 PEP 570 中定義的僅限位置參數。 第一個參數 (argcount) 現在表示位置參數的總數量 (包括僅限位置參數)。types.CodeType
中新增的replace()
方法可用於讓代碼支持 future 特性。
C API 中的改變
-
The
PyCompilerFlags
structure got a new cf_feature_version field. It should be initialized toPY_MINOR_VERSION
. The field is ignored by default, and is used if and only ifPyCF_ONLY_AST
flag is set in cf_flags. (Contributed by Guido van Rossum in bpo-35766.) -
PyEval_ReInitThreads()
函數已從 C API 中移除。 它不應當被顯式地調用;請改用PyOS_AfterFork_Child()
。 (由 Victor Stinner 在 bpo-36728 中貢獻。) -
在 Unix 上,C 擴展不會再被鏈接到 libpython,但 Android 和 Cygwin 例外。 當 Python 被嵌入時,
libpython
不可使用RTLD_LOCAL
加載,而要改用RTLD_GLOBAL
。 之前使用RTLD_LOCAL
已經不可能加載未鏈接到libpython
的 C 擴展了,例如通過Modules/Setup
的*shared*
部分構建的標准庫 C 擴展。 (由 Victor Stinner 在 bpo-21536 中貢獻。) -
在解析或構建值時(例如
PyArg_ParseTuple()
,Py_BuildValue()
,PyObject_CallFunction()
等等)使用形如#
的格式而不定義PY_SSIZE_T_CLEAN
現在將會引發DeprecationWarning
。 它將在 3.10 或 4.0 中被移除。 請參閱 語句解釋及變量編譯 了解詳情。 (由 Inada Naoki 在 bpo-36381 中貢獻。) -
堆分配類型的實例(例如使用
PyType_FromSpec()
創建的實例)會保存一個對其類型對象的引用。 提升這些類型對象引用計數的操作已從PyType_GenericAlloc()
移至更低層級的函數PyObject_Init()
和PyObject_INIT()
。 這使用通過This makes types created throughPyType_FromSpec()
所創建類型的行為與管理代碼中的其他類保持一致。靜態分配類型將不受影響。
在大部分情況下,這應該都不會有附帶影響。 但是,在分配實例后手動提升引用計數的類型(也許是為了繞過漏洞)現在可能永遠不會被銷毀。 要避免這種情況,這些類需要在實例撤銷分配期間在類型對象上調用 Py_DECREF。
要正確地將這些類型移植到 3.8,請應用以下修改:
-
在分配實例之后在類型對象上移除
Py_INCREF
—— 如果有的話。 這可以發生在調用PyObject_New()
,PyObject_NewVar()
,PyObject_GC_New()
,PyObject_GC_NewVar()
或任何其他使用PyObject_Init()
或PyObject_INIT()
的自定義分配器之后。示例:
static foo_struct * foo_new(PyObject *type) { foo_struct *foo = PyObject_GC_New(foo_struct, (PyTypeObject *) type); if (foo == NULL) return NULL; #if PY_VERSION_HEX < 0x03080000 // Workaround for Python issue 35810; no longer necessary in Python 3.8 PY_INCREF(type) #endif return foo; }
確保所有堆分配類型的自定義
tp_dealloc
函數會減少類型的引用計數。static void foo_dealloc(foo_struct *instance) { PyObject *type = Py_TYPE(instance); PyObject_GC_Del(instance); #if PY_VERSION_HEX >= 0x03080000 // This was not needed before Python 3.8 (Python issue 35810) Py_DECREF(type); #endif }
-
-
Py_DEPRECATED()
宏已經針對 MSVC 實現。 這個宏現在必須放在符號名稱之前。示例:
Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);
-
解釋器將不再假裝支持跨發布版本的擴展類型二進制兼容性。 由第三方擴展模塊所導出的
PyTypeObject
應該具有當前 Python 版本所要求的所有空位,包括tp_finalize
(Py_TPFLAGS_HAVE_FINALIZE
不會再在讀取tp_finalize
之前被檢查)。(由 Antoine Pitrou 在 bpo-32388 中貢獻。)
-
PyCode_New()
在第二個位置添加了新的形參 (posonlyargcount) 以支持 PEP 570,指明僅限位置參數的數量。 -
函數
PyNode_AddChild()
和PyParser_AddToken()
現在接受兩個額外的int
參數 end_lineno 和 end_col_offset。 -
The
libpython38.a
file to allow MinGW tools to link directly againstpython38.dll
is no longer included in the regular Windows distribution. If you require this file, it may be generated with thegendef
anddlltool
tools, which are part of the MinGW binutils package:gendef python38.dll > tmp.def dlltool --dllname python38.dll --def tmp.def --output-lib libpython38.a
已安裝的
pythonXY.dll
所在位置將取決於安裝選項以及 Windows 的版本和語言。 請參閱 在Windows上使用 Python 了解更多信息。 該結果庫應當放在與pythonXY.lib
相同的目錄下,這通常是你的 Python 安裝路徑下的libs
目錄。
CPython 字節碼的改變
-
解釋器循環已通過將塊堆棧展開邏輯移入編譯器獲得了簡化。 編譯器現在會發出顯式指令來調整值堆棧並為
break
,continue
和return
調用清除代碼。移除了操作碼
BREAK_LOOP
,CONTINUE_LOOP
,SETUP_LOOP
和SETUP_EXCEPT
。 添加了新的操作碼ROT_FOUR
,BEGIN_FINALLY
,CALL_FINALLY
和POP_FINALLY
。 修改了END_FINALLY
和WITH_CLEANUP_START
的行為。 -
添加了新的操作碼
END_ASYNC_FOR
用於處理當等待async for
循環的下一項時引發的異常。 -
MAP_ADD
現在會預期值為棧的第一個元素而鍵為第二個元素。 作出此改變以使得字典推導式能如 PEP 572 所提議的那樣,鍵總是會在值之前被求值。
演示和工具
- 添加了一個檢測腳本用於對訪問變量的不同方式進行計時:
Tools/scripts/var_access_benchmark.py
。