Mặc dù câu hỏi này đã được hỏi và trả lời nhiều lần (ví dụ, ở đây , ở đây , ở đây và ở đây ) theo ý kiến của tôi câu trả lời không hiện đầy đủ hoặc chính xác chụp tất cả những tác động của -mcờ. Do đó, những điều sau đây sẽ cố gắng cải thiện những gì đã đến trước đó.
TLD
Các -mlệnh thực hiện rất nhiều thứ không phải tất cả trong số họ hẳn sẽ cần tất cả các thời gian. Nói tóm lại: (1) cho phép các tập lệnh python được thực thi thông qua tên modul thay vì tên tệp (2) cho phép một người chọn một thư mục để thêm vào sys.pathđể importgiải quyết và (3) cho phép các tập lệnh python có nhập tương đối hoạt động giống như khi chúng gọi qua import.
Sơ bộ
Để hiểu tầm quan trọng của -mcờ, cần phải làm rõ một thuật ngữ nhỏ.
Đầu tiên, các tệp mà Python có thể thực thi được gọi là các mô-đun. Thông thường các mô-đun chúng tôi quan tâm là *.pycác tệp, nhưng không phải luôn luôn. Ví dụ, có thể viết các mô-đun Python bằng C để thực hiện mã quan trọng. Sự phân biệt này sẽ trở nên quan trọng sau này. Cho đến nay, đủ để biết rằng các mô-đun không phải là gói là các tệp.
Thứ hai, Python xác định các mô-đun thông qua một <modulename>định danh duy nhất (ví dụ import <modulename>:). Đối với mỗi duy nhất <modulename>cũng có một tệp duy nhất ở đâu đó trên máy với sự độc đáo của riêng nó <filename>. Các trình thông dịch Python tuân theo một số quy tắc được xác định rõ ràng được xây dựng xung quanh sys.pathđể ánh xạ <modulename>tới a <filename>(để biết thêm về cách thực hiện điều này, xem PEP 302 ).
Lịch sử phát triển của -m
Với ý nghĩa sơ bộ -mcó thể được giải thích theo nghĩa đơn giản nhất là bảo python tìm một mô-đun để thực hiện thông qua <modulename>chứ không phải <filename>. Nghĩa là, được đưa ra một <filename>hoặc <modulename>cho cùng một mô-đun, hai lệnh sau là tương đương python <filename>hoặc python -m <modulename>.
Trong bản phát hành 2.4.1 ban đầu , nơi -mđã được thêm vào, tất cả những gì nó đã làm là tìm và thực thi các mô-đun bằng cách <modulename>(cùng với việc thêm thư mục hiện tại vào sys.pathđể có thể tìm thấy các mô đun cục bộ). Theo PEP 338, việc triển khai ban đầu cũng bị hạn chế do đó -mkhông thể tham chiếu tên mô-đun trong các gói (nghĩa là phiên bản 2.4.1 sẽ không hỗ trợ tên mô-đun http.servernhưng sẽ hỗ trợ timeit).
Với việc bổ sung PEP 338 , -mchức năng đã được mở rộng để hỗ trợ các <modulename>đại diện trong các gói. Điều này có nghĩa là những cái tên như http.serverbây giờ đã được hỗ trợ đầy đủ -m. Tăng cường này cũng có nghĩa là tất cả các gói trong một tên mô-đun đã được nạp (ví dụ, gói __init__.pyfile đã được thực hiện), cùng với các mô-đun riêng của mình, trong trường hợp các gói sửa đổi của họ __path__trong __init__.py.
Một trường hợp sử dụng đáng chú ý được hỗ trợ -msau PEP 338 là các câu lệnh nhập tuyệt đối trong các gói tùy chỉnh mà không cần phải cài đặt gói sys.path. Điều này có thể đạt được bằng cách sử dụng đơn giản -mđể tải các tệp script từ thư mục gốc của dự án tùy chỉnh (vì thư mục gốc sau đó sẽ được thêm vào sys.path).
Cải tiến tính năng chính cuối cùng -mđã đi kèm với PEP 366 . Với bản cập nhật này -mđã đạt được khả năng hỗ trợ không chỉ nhập tuyệt đối mà cả nhập khẩu tương đối rõ ràng. Điều này đã đạt được bằng cách sửa đổi __package__biến cho mô-đun được đặt tên trong -mlệnh.
Với tất cả các cải tiến trên được thực hiện cho -mnó vẫn còn một thiếu sót lớn. Nó chỉ có thể thực thi các mô-đun được viết bằng python (tức là *.py). Nếu một tên mô-đun đề cập đến một mô-đun biên dịch C được chuyển đến -mlỗi sau đây được tạo ra No code object available for <modulename>.
So sánh -mvới các phương pháp thực hiện khác
Trái tim, -mcờ là một phương tiện để thực thi các tập lệnh python thông qua tên modul chứ không phải tên tệp. Vì lý do này, chúng tôi so sánh nó với hai phương thức nổi tiếng khác để thực hiện các mô-đun: (1) tên tệp với pythonlệnh và (2) tên mô-đun với importcâu lệnh.
Tác dụng của việc thực thi tên tệp bằng pythonlệnh (tức là python <filename>):
- Python's
sys.pathđược sửa đổi để bao gồm vị trí của mô-đun trong độ phân giải nhập
- Biến của mô-đun
__name__được đặt thành'__main__'
- Biến của mô-đun
__package__được đặt thànhNone
- Không có
__init__.pytệp nào sẽ được thực thi cho các gói cha trong<filename>
Hiệu ứng của việc thực thi modulename với importcâu lệnh (tức là import <modulename>):
- Python
sys.pathlà không sửa đổi trong bất kỳ cách nào để giải quyết nhập khẩu
- Biến của mô-đun
__name__được đặt thành tên mô-đun tuyệt đối của nó
- Biến của mô-đun
__package__được đặt thành gói chứa trong<modulename>
- Tất cả
__init__.pycác tệp sẽ được thực thi cho các gói cha mẹ trong<modulename>
Hiệu ứng của việc thực thi modulename với -mcờ (tức là python -m <modulename>):
- Python's
sys.pathđược sửa đổi để bao gồm thư mục hiện tại trong độ phân giải nhập
- Biến của mô-đun
__name__được đặt thành'__main__'
- Biến của mô-đun
__package__được đặt thành gói chứa trong<modulename>
- Tất cả
__init__.pycác tệp sẽ được thực thi cho các gói cha mẹ trong<modulename>
Tóm lược
Các -mlá cờ chỉ đơn giản là một cách khác để thực hiện một kịch bản python qua môđun chứ không phải là tên tập tin. Vì lý do này, người ta cần có ít nhất một sự hiểu biết nhỏ về cách Python ánh xạ các modulename thành tên tệp để tận dụng tối đa lợi thế của nó. Với cách hiểu này mặc dù người ta có được một công cụ mới mạnh mẽ kết hợp các tính năng của importcâu lệnh (ví dụ: hỗ trợ cho câu lệnh nhập tương đối rõ ràng) với sự tiện lợi của câu lệnh dòng pythonlệnh.
-mdường như tìm kiếmmymod1trong đường dẫn thư viện mặc định. Ví dụ:python -m SimpleHTTPServerhoạt động, trong khipython SimpleHTTPServerthất bại vớican't open file 'SimpleHTTPServer': [Errno 2] No such file or directory.