[英]Py2 to Py3: Add future imports
我需要制作一個與 Python3 兼容的舊代碼庫。 代碼需要支持 Python2.7 和 Python3 幾個月。
我想在非常文件中添加這個:
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
我試過這個:
futurize --both-stages --unicode-literals --write --nobackups .
但這僅添加了 unicode-literals 未來導入。 不是其他未來的進口。
我想避免編寫自己的腳本來添加它,因為盲目地添加它是行不通的,因為某些文件已經有這個 header。
如果您只需要確保源代碼編碼標題和 4 個導入語句存在,那么以下腳本將遞歸地通過修改 all.py 文件的目錄下降,以確保這些所需的語句存在。 更新將就地完成,因此明智的做法是確保您有備份,以防在重寫其中一個文件時出現硬件故障。 即使重寫代碼以寫入臨時文件,然后進行最后的“移動”以用新文件替換舊文件,同樣的問題仍然存在。
您應該首先在測試目錄中進行實驗性嘗試,並且一如既往,使用風險自負。
from pathlib import Path
import re
root_path = 'absolute_or_releative_path_to_directory'
encoding_re = re.compile(r'^# -\*- coding: utf-8 -\*-(\r|\r?\n)')
import_re = re.compile(r'\bfrom\s+__future__\s+import\s+((?:absolute_import|division|print_function|unicode_literals))\b')
all_imports = ['absolute_import', 'division', 'print_function', 'unicode_literals']
all_imports_set = set(all_imports)
for path in Path(root_path).glob('**/*.py'):
with open(path, 'r', encoding='utf-8') as f:
source = f.read()
# Look for source encoding header:
m = encoding_re.search(source)
# Look for the 4 imports:
found_imports = set(import_re.findall(source))
if m and len(found_imports) == 4:
# Found encoding line and all 4 imports,
# so there is nothing to do:
continue
# Else we need to write out a replacement file:
with open(path, 'w', encoding='utf-8') as f:
if not m or len(found_imports) < 4:
# Did not find encoding line or we must write out
# at least one import. In either case we must write
# the encoding line to ensure it is the first line:
print('# -*- coding: utf-8 -*-', file=f)
if not found_imports:
# Found no imports so write out all 4:
missing_imports = all_imports
else:
# Found 1 to 4 import statement; compute the missing ones:
missing_imports = all_imports_set - found_imports
for import_name in missing_imports:
print(f'from __future__ import {import_name}', file=f)
# Print remaining source:
print(source, end='', file=f)
從文檔:
除非將
--all-imports
命令行選項傳遞給futurize
,否則只會添加那些認為必要的__future__
導入,在這種情況下它們都會被添加。
如果您希望futurize
無條件地添加所有這些導入,則需要將--all-imports
標志傳遞給它。
首先定義一個您希望成為每個文件的導入列表。
您可以使用將recursive
關鍵字參數設置為True
的glob.glob()
方法,以便遞歸搜索給定路徑中的.py
文件。
對於返回的每個文件名,在讀取其內容后,您可以使用過濾器過濾掉文件中已經存在的導入,並且只寫入那些不存在的導入:
import glob
lines = [
"from __future__ import absolute_import",
"from __future__ import division",
"from __future__ import print_function",
"from __future__ import unicode_literals"
]
for file in glob.glob('/project/**/*.py', recursive=True): # replace project with the path
with open(file, 'r+') as f:
content = f.read().splitlines() # Read into a list of lines
f.seek(0, 0) # To the top of the file
lines2 = [line for line in lines if line not in content] # Filter out existing imports
f.write("\n".join(lines2 + content))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.