优雅整理Python中的import
“阅读本文大概需要7分钟。
你好,我是测试蔡坨坨。
众所周知,Python拥有丰富的标准库和第三方库,如果我们需要在Python中使用这些库,就需要使用import语句进行导入。通常情况下,项目中用到的库不止一个,所以会有很多的import语句,并且这些模块的种类也有多种,如标准模块、第三方模块、自定义模块等,如何对导入模块的顺序进行排序成了问题。并且随着代码的迭代,以前导入的模块可能后面就不需要用到,但是它还是会在Python文件中,每次都需要手动删除。
以上两种情况对于强迫症来说很不友好。
所以,今天我们就来介绍两个非常好用的Python第三方库——isort和autoflake,可以帮助我们自动、快速、优雅整理Python项目中的import。
使用isort对import进行排序,使用autoflake删除未使用的import。
isort
PEP8对import的规范
官方文档:https://peps.python.org/pep-0008/#imports
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants. (导入通常放在文件顶部,模块注释和文档字符串之后,模块全局变量和常量之前)
Imports should be grouped in the following order:
- Standard library imports. (首先导入标准库模块)
- Related third party imports. (其次导入第三方模块)
- Local application/library specific imports. (最后导入自定义模块)
属于同一组的导入语句按字母顺序排列。
You should put a blank line between each group of imports. (每组导入之间有一个空行)
isort的作用
使用isort可以自动将Python模块中的import语句进行排序,并自动按类型分类,满足以上所说的PEP8规范。
官方文档:https://pycqa.github.io/isort/docs/configuration/options.html
安装isort
pip install isort
效果
没有 isort 之前,非常凌乱:
from django.conf import settings
from web.utils.pagination import Pagination
from django.core.serializers import json
from django.db.models import Count, F
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse
import time
from django.views.decorators.csrf import csrf_exempt
from bs4 import BeautifulSoup
import json
import os
from web.forms.manage_form import ArticleModelForm
from web import models
执行 isort 命令:
isort .
isort 之后:
import json # 第一组为标准模块 同一组按字母顺序排序
import os
import time
# 每组之间空一行
from bs4 import BeautifulSoup # 第二组为第三方模块 同一组按字母顺序排序
from django.conf import settings
from django.core.serializers import json
from django.db.models import Count, F
from django.http import HttpResponse, JsonResponse
from django.shortcuts import redirect, render
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
from web import models # 第三组为自定义模块 同一组按字母顺序排序
from web.forms.manage_form import ArticleModelForm
from web.utils.pagination import Pagination
isort命令
指定文件
isort caituotuo.py caituotuo2.py
当前目录所有py文件
isort .
仅查看修改建议,不修改文件
isort caituotuo.py --diff
仅在未引入语法错误的情况下应用更改
isort --atomic .
跳过指定文件(文件名、目录名、文件路径)
isort -skip caituotuo.py
isort -s caituotuo.py
强制所有import都出现在单行上
isort --force-single-line-imports
参数实在太多,默认不加参数完全够用,需要用到哪个参数再去官网查阅即可。
在Python中使用
import isort
isort.file("caituotuo.py")
跳过某个模块
import module # isort:skip
跳过整个文件
"""
isort:skip_file
import os
autoflake
简介
官方文档:https://pypi.org/project/autoflake/
autoflake removes unused imports and unused variables from Python code.
autoflake also removes useless pass statements by default.
autoflake可以移除Python代码中未使用的导入和变量,以及无用的pass语句,从而精简代码。
By default, autoflake only removes unused imports for modules that are part of the standard library. (Other modules may have side effects that make them unsafe to remove automatically.)
默认情况下,autoflake仅删除未使用的标准库模块import,不会自动删除其他模块(第三方模块和自定义模块)的import,因为其他模块可能会有副作用,但是可以使用
--remove-all-unused-imports
参数来删除所有未使用的导入,无论是否标准库模块,只要未使用都可以删除。还可以使用
--imports
参数来指定模块。
默认情况下,autoflake禁用了删除未使用的变量,要删除未使用的变量,可以使用
--remove-unused-variables
参数来进行删除。
安装
pip install autoflake
命令
格式
通用格式:
autoflake [参数] [文件]
可选参数
参数 |
英文解释 |
中文解释 |
---|---|---|
-h, --help |
show this help message and exit |
显示帮助信息并退出 |
-c, --check |
return error code if changes are needed |
如果需要更改则返回错误代码 |
-cd, --check-diff |
return error code if changes are needed, also display file diffs |
如果需要更改则返回错误代码,并显示文件差异 |
--imports IMPORTS |
by default, only unused standard library imports are removed; specify a comma-separated list of additional modules/packages |
指定要删除未引用导入的模块 |
--remove-all-unused-imports |
remove all unused imports (not just those from the standard library) |
删除所有未使用的导入(不只是标准库模块,还有第三方模块也会被删除) |
-r, --recursive |
drill down directories recursively |
递归目录 |
-j n, --jobs n |
number of parallel jobs; match CPU count if value is 0 (default: 0) |
|
--exclude globs |
exclude file/directory names that match these comma-separated globs ignore pass statements after a newline ending on '"""' |
|
--version |
show program's version number and exit |
|
--quiet |
Suppress output if there are no issues |
|
-v, --verbose |
print more verbose logs (you can repeat -v to make it more verbose) |
|
--stdin-display-name |
STDIN_DISPLAY_NAME the name used when processing input from stdin |
|
--config CONFIG_FILE |
Explicitly set the config file instead of auto determining based on file location |
|
-i, --in-place |
make changes to files instead of printing diffs |
直接删除未使用的import,而不是打印 |
-s, --stdout |
print changed text to stdout. defaults to true when formatting stdin, or to false otherwise |
|
--remove-unused-variables |
remove unused variables |
删除未使用的变量 |
删除未使用的标准库模块
格式:
autoflake -i 模块
或
autoflake --in-place 模块
举栗:
autoflake -i run.py
执行命令前:
执行命令后:
删除所有未使用的import
格式:
autoflake -i --remove-all-unused-imports 模块
举栗:
autoflake -i --remove-all-unused-imports run.py
执行命令前:
执行命令后:
删除未使用的变量
格式:
autoflake -i --remove-unused-variables <文件名>
举栗:
autoflake -i --remove-unused-variables run.py
执行命令前:
执行命令后:
指定模块
autoflake --imports=django,requests,urllib3 <文件名>
isort+autoflake
将isort和autoflake写成import_util.py,放到项目中,每次自动运行:
# author: 测试蔡坨坨
# datetime: 2022/12/4 16:59
# function: 使用isort对import进行排序,使用autoflake删除未使用的import
import os
class ImportUtil:
def rm_all_unused_import_and_isort(self,project_path):
移除项目中所有未使用的import,并按PEP8标准对import排序
@return:
filepath_list = []
all_module_list = []
all_module_str = ""
for root, folder_names, file_names in os.walk(project_path):
for file_name in file_names:
# 文件绝对路径
file_path = root + os.sep + file_name
filepath_list.append(file_path)
# 最后一个.号进行拆分
file = str(file_path).rsplit(".")
if len(file) == 2:
if str(file[1]) == "py":
all_module_list.append(str(file[0]) + ".py")
# 找出项目中所有.py文件,拼接成字符串,用空格隔开
for i in all_module_list:
all_module_str += str(i) + " "
cmd1 = "autoflake -i --remove-all-unused-imports {}".format(all_module_str)
cmd2 = "isort {}".format(project_path)
os.system(cmd1)
os.system(cmd2)
print(cmd1)
print(cmd2)