首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Py2到Py3:添加未来导入

Py2到Py3:添加未来导入
EN

Stack Overflow用户
提问于 2022-01-28 16:33:49
回答 3查看 296关注 0票数 5

我需要使一个旧的代码库与Python3兼容。代码需要支持Python2.7和Python3几个月。

我想在下面的文件中添加以下内容:

代码语言:javascript
复制
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

我试过这个:

代码语言:javascript
复制
futurize --both-stages --unicode-literals --write --nobackups .

但这只会增加unicode文本的未来导入。而不是其他未来的进口。

我想避免编写我自己的脚本来添加这个,因为盲目地添加这个不起作用,因为有些文件已经有了这个头。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-02-03 08:23:36

来自文档

只有那些被认为是必要的__future__导入才会被添加,除非--all-imports命令行选项被传递给futurize,在这种情况下,它们都会被添加。

如果希望futurize无条件地添加所有这些导入,则需要传递--all-imports标志。

票数 4
EN

Stack Overflow用户

发布于 2022-01-31 16:32:38

如果您只需要确保源代码编码标题和4个导入语句都存在,那么下面的脚本将递归地下降到修改所有.py文件的目录中,确保这些必需的语句都存在。更新将在适当的地方进行,所以最好确保在重写其中一个文件时出现硬件故障时备份。即使代码被重写为写入临时文件,然后执行最后的“移动”,以用新的替换旧的,同样的问题仍然存在。

您应该首先在一个测试目录中实验地尝试这一点,并且像往常一样,自己冒险使用它。

代码语言:javascript
复制
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)
票数 6
EN

Stack Overflow用户

发布于 2022-02-02 20:11:19

首先,定义要成为每个文件的导入列表。

您可以使用glob.glob()方法,将recursive关键字参数设置为True,以便它在给定路径内递归搜索.py文件。

对于返回的每个文件名,在读取其内容后,您可以使用一个筛选器筛选出文件中已经存在的导入,并且只编写那些不存在的导入:

代码语言:javascript
复制
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))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70897060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档