-m 스위치의 목적은 무엇입니까?


174

전화하는 것의 차이점이 무엇인지 설명해 주시겠습니까?

python -m mymod1 mymod2.py args

python mymod1.py mymod2.py args

이 두 경우 모두 같다 mymod1.py라고하고 sys.argv있다

['mymod1.py', 'mymod2.py', 'args']

그래서 무엇 -m을위한 스위치?


내가 틀렸다면 나를 수정하십시오. 그러나 기본 라이브러리 경로에서 -m검색하는 것 같습니다 mymod1. 예 : python -m SimpleHTTPServer작동하지만 python SimpleHTTPServer실패합니다 can't open file 'SimpleHTTPServer': [Errno 2] No such file or directory.
Basj

7
실제로 여기에 대한 대답이 명확하게 발견되었습니다. stackoverflow.com/questions/46319694/…
Casebash

답변:


137

PEP 338Rationale 섹션의 첫 줄은 다음 과 같습니다.

Python 2.4는 명령 줄 스위치 -m을 추가하여 스크립트로 실행하기 위해 Python 모듈 네임 스페이스를 사용하여 모듈을 찾을 수 있도록합니다. 동기 부여 예제는 pdb 및 프로파일과 같은 표준 라이브러리 모듈이며 Python 2.4 구현은 이러한 제한된 목적에 적합합니다.

따라서 현재 디렉토리의 파일뿐만 아니라 Python의 검색 경로에서 모든 모듈을 지정할 수 있습니다. python mymod1.py mymod2.py args정확히 같은 효과 가있는 것이 맞습니다 . Scope of this proposal섹션 의 첫 번째 줄은 다음 과 같습니다.

Python 2.4에서 -m을 사용하여 찾은 모듈은 파일 이름이 명령 줄에 제공된 것처럼 실행됩니다.

-m더하는 것은 PEP (338)의 나머지 부분이 약의 무슨 등 패키지의 일부 모듈, 작업을 같이 할 수 있습니다. 자세한 내용은 읽어보십시오.


47
내가 가장 좋아하는 사용법은 -m입니다 python -m SimpleHTTPServer. USB 플래시 드라이브를 사용하지 않고 일부 파일을 공유해야 할 때 정말 편리합니다.
arifwn

21
@arifwn Python3을 실행하면 약간의 업데이트가 필요하며 python -m http.server여전히 훌륭합니다!
키트 Roed

12
TL; DR : 1) 당신은 실행할 수 있고 python -m package.subpackage.module정상적인 해결 기계가 사용될 것입니다, 당신은 정확한 .py파일 을 가리킬 필요가 없습니다 . 2) 패키지가 길을 따라로드되기 때문에 해결 방법없이 실행되는 모듈에서 상대 가져 오기를 수행 할 수 있습니다. 3) 절대 가져 오기는 .py파일이 있는 디렉토리가 아니라 현재 디렉토리를 기반으로합니다 ( 스크립트가에있는 경우가 아니라 ''의 헤드 에 있음 ). sys.path/path/to/my/path/to/my/script.py
clacke

이 답변이 명확하지 않은 것은 실행 가능한 모듈의 하위 집합 ( 예 : __main__.py파일) 에서만 작동한다는 것 입니다. 대부분은 python -m sys 'print(sys.version)'실패 하지 않으며 예를 들어 실패합니다 python: No code object available for sys. 답변에서 명확하게 제안하십시오.
smci

19

언급이의 가치 패키지가 파일이있는 경우에만 작동합니다__main__.py 그렇지 않으면이 패키지를 직접 실행할 수 없습니다.

python -m some_package some_arguments

파이썬 인터프리터는 __main__.py패키지 경로에서 실행할 파일을 찾습니다 . 다음과 같습니다.

python path_to_package/__main__.py somearguments

다음 후에 컨텐츠를 실행합니다.

if __name__ == "__main__":

2
패키지 초기화 파일은 어떻습니까? 기본 파일이 있으면 init도 호출됩니까?
변수

@variable 예 init .py는 main .py가 호출 되기 전에 호출됩니다
Mark Rucker

1

이 질문이 여러 번 (예, 여기 , 여기 , 여기 , 여기 ) 여러 번 묻고 대답되었지만 기존 답변이 -m깃발 의 모든 의미를 완전히 또는 간결하게 포착하지는 않습니다 . 따라서 다음은 이전에 있었던 것을 개선하려고 시도합니다.

소개 (TLDR)

-m명령은 많은 것들을 수행하지만 모든 것이 항상 필요한 것은 아닙니다. 간단히 말하면 : (1) 파일 이름 대신 모듈 이름을 통해 파이썬 스크립트를 실행할 수 있습니다. (2) 해결 을 sys.path위해 추가 할 디렉토리를 선택할 수 import있으며 (3) 상대적 가져 오기가있는 파이썬 스크립트를 명령 줄에서 실행할 수 있습니다 .

예비

-m깃발 을 설명하기 위해서는 먼저 약간의 용어를 분명히해야합니다.

먼저, 파이썬의 기본 조직 단위를 모듈 이라고 합니다 . 모듈은 코드 모듈과 패키지 모듈의 두 가지 종류 중 하나로 제공됩니다. 코드 모듈은 python 실행 코드가 포함 된 파일입니다. 패키지 모듈은 다른 모듈 (코드 모듈 또는 패키지 모듈)을 포함하는 디렉토리입니다. 가장 일반적인 유형의 코드 모듈은 *.py파일이고 가장 일반적인 유형의 패키지 모듈은 __init__.py파일을 포함하는 디렉토리 입니다.

둘째, 모든 모듈은 유일하게 두 가지 방법으로 확인할 수 있습니다 <modulename><filename>. 모듈은 대부분 파이썬 코드 (예 :)의 모듈 import <modulename>이름과 명령 줄 (예 :)의 파일 이름으로 식별됩니다 python <filename>. 모든 파이썬 인터프리터는 잘 정의 된 규칙 세트를 통해 모듈 이름을 파일 이름으로 변환 할 수 있습니다. 이러한 규칙은 sys.path변수 에 달려 있으므로이 값을 변경하여 매핑을 변경할 수 있습니다 (이 방법에 대한 자세한 내용은 PEP 302 참조 ).

셋째, 모든 모듈 (코드 및 패키지 모두)을 실행할 수 있습니다 (이를 통해 모듈과 관련된 코드가 Python 인터프리터에 의해 평가됨). 실행 방법과 모듈 유형에 따라 어떤 코드가 평가되고 언제 변경되는지가 약간 변경 될 수 있습니다. 예를 들어, 하나를 통해 실행하는 패키지 모듈 경우 python <filename>다음을 <filename>/__init__.py계산한다 하였다 <filename>/__main__.py. 반면에 하나의 패키지 모듈을 통해 동일한 패키지 모듈을 실행 import <modulename>하면 패키지 만 __init__.py실행됩니다.

역사적 발전 -m

-m 플래그는 Python 2.4.1 에서 처음 도입되었습니다 . 처음에 유일한 목적은 실행할 파이썬 모듈을 식별하는 대체 수단을 제공하는 것이 었습니다. 우리가 모두 알고있는 경우 즉, <filename><modulename>모듈에 대한 다음 두 명령은 상당했다 : python <filename> <args>python -m <modulename> <args>. 또한 PEP 338 에 따르면 이 반복은 -m최상위 수준의 모듈 이름 (즉, 개입 패키지없이 sys.path에서 직접 찾을 수있는 모듈)에서만 작동했습니다.

의 완료와 함께 PEP 338-m 기능은 지원 확장 된 <modulename>최고 수준의 모듈 명을 넘어 표현. 이것은 http.server이제 완전히 지원되는 것과 같은 이름을 의미했습니다 . 또한이 개선 사항 __init__.py은 모듈 자체와 함께 모듈의 모든 패키지가로드 (즉, 모든 패키지 파일이 평가됨) 되었음을 의미 합니다.

에 대한 최종 주요 기능 향상은 PEP 366-m 과 함께 제공되었습니다 . 이번 업데이트로 절대 수입뿐만 아니라 명시 적 상대 수입도 지원할 수있게되었습니다. 이는 명령 에서 명명 된 모듈 의 변수를 수정하여 수행되었습니다 .-m__package__-m

사용 사례

-m 플래그에 대한 두 가지 주목할만한 사용 사례가 있습니다.

  1. 파일 이름을 모르는 명령 줄에서 모듈을 실행합니다. 이 사용 사례는 파이썬 인터프리터가 모듈 이름을 파일 이름으로 변환하는 방법을 알고 있다는 사실을 이용합니다. 이것은 명령 행에서 stdlib 모듈 또는 타사 모듈을 실행하려는 경우에 특히 유리합니다. 예를 들어, http.server모듈 의 파일 이름을 아는 사람은 거의 없지만 대부분의 사람들은 모듈 이름을 알고 있으므로 명령 줄에서를 사용하여 실행할 수 있습니다 python -m http.server.

  2. 절대 가져 오기가 포함 된 로컬 패키지를 설치하지 않고 실행합니다. 이 사용 사례는 PEP 338에 자세히 설명되어 있으며 현재 작업 디렉토리가 sys.path모듈의 디렉토리 가 아니라 추가 된 사실을 활용합니다 . 이 사용 사례는 pip install -e .개발 / 편집 모드에서 패키지를 설치하는 데 사용 하는 것과 매우 유사 합니다.

단점

-m수년 에 걸쳐 모든 개선 사항이 있었지만 여전히 한 가지 큰 단점이 있습니다-파이썬으로 작성된 코드 모듈 (예 : * .py) 만 실행할 수 있습니다. 예를 들어, -mC 컴파일 된 코드 모듈을 실행하는 데 사용되는 경우 다음 오류가 발생합니다 No code object available for <modulename>( 자세한 내용 은 여기 참조).

자세한 비교

python 명령 (예 :)을 통한 모듈 실행의 영향 python <filename>:

  • sys.path 최종 디렉토리를 포함하도록 수정되었습니다. <filename>
  • __name__ 로 설정 '__main__'
  • __package__ 로 설정 None
  • __init__.py 모든 패키지에 대해 평가되지 않음 (패키지 모듈에 대한 자체 패키지 포함)
  • __main__.py패키지 모듈에 대해 평가됩니다. 코드는 코드 모듈에 대해 평가됩니다.

import 문을 통한 모듈 실행의 영향 (예 :) import <modulename>:

  • sys.path되어 있지 어떤 방식으로 수정
  • __name__ 절대 형태로 설정 <modulename>
  • __package__ 에서 바로 상위 패키지로 설정됩니다. <modulename>
  • __init__.py 모든 패키지에 대해 평가됩니다 (패키지 모듈에 대한 자체 패키지 포함).
  • __main__.py되고 있지 패키지 모듈의 평가; 코드는 코드 모듈에 대해 평가됩니다

-m 플래그 (예 :)를 통한 모듈 실행의 영향 python -m <modulename>:

  • sys.path 현재 디렉토리를 포함하도록 수정되었습니다.
  • __name__ 로 설정 '__main__'
  • __package__ 에서 바로 상위 패키지로 설정됩니다. <modulename>
  • __init__.py 모든 패키지에 대해 평가됩니다 (패키지 모듈에 대한 자체 패키지 포함).
  • __main__.py패키지 모듈에 대해 평가됩니다. 코드는 코드 모듈에 대해 평가됩니다

결론

-m플래그는 가장 간단하게 파일 이름 대신 모듈 이름을 사용하여 명령 줄에서 파이썬 스크립트를 실행하는 수단입니다. 또한 python 명령 줄의 편의성과 함께 문장의 기능 (예 : 명시 적 상대 가져 오기 및 자동 패키지 평가 지원)을 -m결합한 추가 기능을 제공합니다 .import__init__


python -m packagename여기에 언급 된대로 패키지 호출 사용을 추가 할 수 있습니까 : stackoverflow.com/a/53772635/1779091
변수

@variable good idea를 포함하는 "Use Case"섹션을 추가했습니다.
Mark Rucker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.