Thực thi mã Python với tùy chọn -m hoặc không
Sử dụng -m
cờ.
Kết quả khá giống nhau khi bạn có một tập lệnh, nhưng khi bạn phát triển một gói, không có -m
cờ, không có cách nào để nhập hoạt động chính xác nếu bạn muốn chạy một gói con hoặc mô-đun trong gói làm mục nhập chính. chỉ vào chương trình của bạn (và tin tôi đi, tôi đã thử.)
Các tài liệu
Giống như tài liệu trên cờ -m nói:
Tìm kiếm sys.path cho mô-đun được đặt tên và thực thi nội dung của nó dưới dạng __main__
mô-đun.
và
Như với tùy chọn -c, thư mục hiện tại sẽ được thêm vào phần đầu của sys.path.
vì thế
python -m pdb
gần tương đương với
python /usr/lib/python3.5/pdb.py
(giả sử bạn không có gói hoặc tập lệnh trong thư mục hiện tại của mình có tên là pdb.py)
Giải trình:
Hành vi được thực hiện "cố ý giống với" kịch bản.
Nhiều mô-đun thư viện tiêu chuẩn chứa mã được gọi khi thực thi chúng dưới dạng tập lệnh. Một ví dụ là mô-đun thời gian:
Một số mã python được thiết kế để chạy dưới dạng mô-đun: (Tôi nghĩ ví dụ này tốt hơn ví dụ doc tùy chọn dòng lệnh)
$ python -m timeit '"-".join(str(n) for n in range(100))'
10000 loops, best of 3: 40.3 usec per loop
$ python -m timeit '"-".join([str(n) for n in range(100)])'
10000 loops, best of 3: 33.4 usec per loop
$ python -m timeit '"-".join(map(str, range(100)))'
10000 loops, best of 3: 25.2 usec per loop
Và từ các điểm nổi bật của ghi chú phát hành cho Python 2.4 :
Tùy chọn dòng lệnh -m - tên mô-đun python -m sẽ tìm một mô-đun trong thư viện chuẩn và gọi nó. Ví dụ, python -m pdb
tương đương vớipython /usr/lib/python2.4/pdb.py
Theo dõi câu hỏi
Ngoài ra, Tài liệu tham khảo về Python Essential của David Beazley giải thích nó là "Tùy chọn -m chạy mô-đun thư viện như một tập lệnh thực thi bên trong __main__
mô-đun trước khi thực thi tập lệnh chính".
Nó có nghĩa là bất kỳ mô-đun nào bạn có thể tra cứu bằng câu lệnh nhập đều có thể được chạy như là điểm đầu vào của chương trình - nếu nó có một khối mã, thường ở gần cuối, với if __name__ == '__main__':
.
-m
mà không cần thêm thư mục hiện tại vào đường dẫn:
Một bình luận ở đây ở nơi khác nói:
Tùy chọn -m đó cũng thêm thư mục hiện tại vào sys.path, rõ ràng là một vấn đề bảo mật (xem: tấn công tải trước). Hành vi này tương tự như thứ tự tìm kiếm thư viện trong Windows (trước khi nó được cứng lại gần đây). Thật đáng tiếc khi Python không theo xu hướng và không cung cấp một cách đơn giản để tắt thêm. tới sys.path
Chà, điều này chứng tỏ sự cố có thể xảy ra - (trong windows, hãy xóa dấu ngoặc kép):
echo "import sys; print(sys.version)" > pdb.py
python -m pdb
3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul 5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
Sử dụng -I
cờ để khóa điều này cho môi trường sản xuất (mới trong phiên bản 3.4):
python -Im pdb
usage: pdb.py [-c command] ... pyfile [arg] ...
etc...
từ các tài liệu :
-I
Chạy Python ở chế độ cô lập. Điều này cũng ngụ ý -E và -s. Ở chế độ biệt lập, sys.path không chứa thư mục của script cũng như thư mục site-package của người dùng. Tất cả các biến môi trường PYTHON * cũng bị bỏ qua. Các hạn chế khác có thể được áp đặt để ngăn người dùng tiêm mã độc.
Làm gì __package__
?
Tuy nhiên, nó cho phép nhập tương đối rõ ràng, không đặc biệt là vi phạm đối với câu hỏi này - hãy xem câu trả lời này tại đây: Mục đích của thuộc tính "__package__" trong Python là gì?
PYTHONPATH=test python -m foo.bar
nghĩa là gì? Bạn có thể giải thích nó chi tiết, xin vui lòng?