모든 Pythonista가 알고 싶은 import 순서를 프로젝트 내에서 통합하는 방법
이 기사 is 무엇? (TL; DR)
isort을 사용하여 가져 오기 정렬
Python의 import 순서가 규약으로 정해지지 않은 문제
Python의 import 순서는 PEP8에 다음과 같이 설명되어 있습니다.
- 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:
1. Standard library imports.
2. Related third party imports.
3. Local application/library specific imports.
You should put a blank line between each group of imports.
즉, 다음 순서로 공행을 끼워 쓰면 OK입니다!
1. 표준 라이브러리
2. 타사 라이브러리
3. 자작 라이브러리
...에?
표준 라이브러리끼리의 순서는 어떻게 하면 좋을까?from pathlib import Path
와 import sys
는 어느 쪽이 먼저인가?
실은 Python 규약에서는, 표준 라이브러리끼리의 순서등에 대해서는 정해져 있지 않습니다!
즉, 프로젝트 내에서 통일하는 기준을 정해주지 않으면, 사람에 의해 화려한 쓰는 방법을 해 버리게 됩니다!
isort를 사용한 솔루션
isort이라는 도구를 사용하여 프로젝트 내에서 통합 규칙을 결정하고 운영합니다.
- 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:
1. Standard library imports.
2. Related third party imports.
3. Local application/library specific imports.
You should put a blank line between each group of imports.
isort이라는 도구를 사용하여 프로젝트 내에서 통합 규칙을 결정하고 운영합니다.
pip install isort
에서 isort 설치 ~/.isort.cfg
파일 편집 isort -rc .
를 실행하여 프로젝트의 모든 파일을 정의한 규칙으로 정렬 기본 설정(.isort.cfg 파일을 만들지 않는 경우)은 다음과 같이 정렬됩니다!
기본적으로 PEP8을 따라 정렬하여 좋은 느낌입니다
정렬 전
import os
import sys
from pathlib import Path
import numpy as np
import pandas as pd
import boto3
import mylib1
import mylib2
정렬 후
import os
import sys
from pathlib import Path
import boto3
import numpy as np
import pandas as pd
import mylib1
import mylib2
덤: 정렬되지 않은 파일을 커밋할 수 없게 합니다.
사전 커밋을 사용하여 정렬되지 않은 파일을 커밋할 수 없도록 하려면 다음과 같이 파일을 편집합니다!
참고: htps : // 기 st. 기주 b. 코 m/아 c데야/8717683
1. cp .git/hooks/pre-commit.sample .git/hooks/pre-commit
하여 사전 커밋 파일 만들기
2. pre-commit 파일을 다음 내용으로 덮어쓰기
※프로젝트에 의해서 고유의 값이 될 수 있는 개소를 TODO로서 기재하고 있다(2개소) 때문에, 거기를 수정할 필요가 있습니다.
※ which python
이나 which isort
의 결과의 패스를 지정해 올리면 OK입니다.
사전 커밋#!/usr/bin/env PYTHONIOENCODING=utf-8 [TODO: プロジェクトのPython環境を記載する]
# encoding: utf-8
"""Git pre-commit hook which lints Python, JavaScript, SASS and CSS"""
from __future__ import absolute_import, print_function, unicode_literals
import os
import subprocess
import sys
FS_ENCODING = sys.getfilesystemencoding()
def check_linter(cmd, files, **kwargs):
if not files:
return
print('Running %s' % cmd[0])
return subprocess.check_output(cmd + files, stderr=subprocess.STDOUT, **kwargs).decode(FS_ENCODING)
def filter_ext(extension, files, exclude=None):
files = [f for f in files if f.endswith(extension)]
if exclude is not None:
files = [i for i in files if exclude not in i]
return files
def lint_files(changed_files):
changed_files = [i.strip() for i in changed_files.splitlines() if '/external/' not in i]
changed_extensions = {ext for root, ext in map(os.path.splitext, changed_files)}
if '.py' in changed_extensions:
py_files = filter_ext('.py', changed_files)
check_linter(['[TODO: プロジェクトのisortパスを記載する]', '-c'], py_files)
if '.js' in changed_extensions:
check_linter(['eslint'], filter_ext('.js', changed_files, exclude='.min.'))
if '.scss' in changed_extensions:
try:
check_linter(['scss-lint'], filter_ext('.scss', changed_files))
except subprocess.CalledProcessError as exc:
if exc.returncode == 1:
# scss-lint rc=1 means no message more severe than a warning
pass
else:
raise
if '.css' in changed_extensions:
check_linter(['csslint'], filter_ext('.css', changed_files, exclude='.min.'))
if __name__ == "__main__":
os.chdir(os.path.join(os.path.dirname(__file__), '..', '..'))
changed_files = subprocess.check_output('git diff --cached --name-only --diff-filter=ACM'.split())
changed_files = changed_files.decode(FS_ENCODING)
try:
lint_files(changed_files)
except subprocess.CalledProcessError as exc:
print('Quality check failed:', file=sys.stderr)
print(' '.join(exc.cmd), file=sys.stderr)
if exc.output:
output = exc.output.decode(FS_ENCODING)
print('\t', '\n\t'.join(output.splitlines()), sep='', file=sys.stderr)
sys.exit(1)
pre-commit 파일을 작성하고, isort 순서가 지정된 방법이 아닌 파일이 있는 경우, 다음과 같은 에러 메세지가 나와 commit에 실패합니다.
コミットはエラーで失敗しました
0 file committed, 1 file failed to commit: [invalid!!]test commit
ERROR: /Users/xxx/PycharmProjects/isort_test/incorrect_isort.py Imports are incorrectly sorted.
위의 오류로 커밋이 실패하면 isort [ソートしたいファイルパス]
를 실행하여 import 순서를 정렬하면 commit 할 수 있습니다!
덤: PyCharm 사용자용
PyCharm에서 하나의 명령으로 isort를 실행하지 않으려면 명령을 외부 도구로 등록 할 수 있습니다!
커뮤니티 버전에서도 사용할 수 있습니다!
참고: htps : // 기주 b. 코 m / 치모 thyc 로 s ぇ y / 이소 rt / 이스에 s / 258
#!/usr/bin/env PYTHONIOENCODING=utf-8 [TODO: プロジェクトのPython環境を記載する]
# encoding: utf-8
"""Git pre-commit hook which lints Python, JavaScript, SASS and CSS"""
from __future__ import absolute_import, print_function, unicode_literals
import os
import subprocess
import sys
FS_ENCODING = sys.getfilesystemencoding()
def check_linter(cmd, files, **kwargs):
if not files:
return
print('Running %s' % cmd[0])
return subprocess.check_output(cmd + files, stderr=subprocess.STDOUT, **kwargs).decode(FS_ENCODING)
def filter_ext(extension, files, exclude=None):
files = [f for f in files if f.endswith(extension)]
if exclude is not None:
files = [i for i in files if exclude not in i]
return files
def lint_files(changed_files):
changed_files = [i.strip() for i in changed_files.splitlines() if '/external/' not in i]
changed_extensions = {ext for root, ext in map(os.path.splitext, changed_files)}
if '.py' in changed_extensions:
py_files = filter_ext('.py', changed_files)
check_linter(['[TODO: プロジェクトのisortパスを記載する]', '-c'], py_files)
if '.js' in changed_extensions:
check_linter(['eslint'], filter_ext('.js', changed_files, exclude='.min.'))
if '.scss' in changed_extensions:
try:
check_linter(['scss-lint'], filter_ext('.scss', changed_files))
except subprocess.CalledProcessError as exc:
if exc.returncode == 1:
# scss-lint rc=1 means no message more severe than a warning
pass
else:
raise
if '.css' in changed_extensions:
check_linter(['csslint'], filter_ext('.css', changed_files, exclude='.min.'))
if __name__ == "__main__":
os.chdir(os.path.join(os.path.dirname(__file__), '..', '..'))
changed_files = subprocess.check_output('git diff --cached --name-only --diff-filter=ACM'.split())
changed_files = changed_files.decode(FS_ENCODING)
try:
lint_files(changed_files)
except subprocess.CalledProcessError as exc:
print('Quality check failed:', file=sys.stderr)
print(' '.join(exc.cmd), file=sys.stderr)
if exc.output:
output = exc.output.decode(FS_ENCODING)
print('\t', '\n\t'.join(output.splitlines()), sep='', file=sys.stderr)
sys.exit(1)
コミットはエラーで失敗しました
0 file committed, 1 file failed to commit: [invalid!!]test commit
ERROR: /Users/xxx/PycharmProjects/isort_test/incorrect_isort.py Imports are incorrectly sorted.
PyCharm에서 하나의 명령으로 isort를 실행하지 않으려면 명령을 외부 도구로 등록 할 수 있습니다!
커뮤니티 버전에서도 사용할 수 있습니다!
참고: htps : // 기주 b. 코 m / 치모 thyc 로 s ぇ y / 이소 rt / 이스에 s / 258
※Pycharm을 일본어화하고 있으므로 일부 화상이 다를지도 모릅니다.
요약
The Zen of Python에 따라 단 하나의 즐거운 방법을 팀에서 모색해 봅시다!
마사카리 환영합니다!
There should be one-- and preferably only one --obvious way to do it.
뭔가 좋은 방법이 있을 것이다. 누가 봐도 분명한, 단 하나의 방법이.
by The Zen of Python
Reference
이 문제에 관하여(모든 Pythonista가 알고 싶은 import 순서를 프로젝트 내에서 통합하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/tez/items/5c9a42b075d75d4a5aac
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(모든 Pythonista가 알고 싶은 import 순서를 프로젝트 내에서 통합하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tez/items/5c9a42b075d75d4a5aac텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)