簡體   English   中英

Py2 到 Py3:添加未來的導入

[英]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關鍵字參數設置為Trueglob.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM