Là gì __main__.py
file cho, những gì sắp xếp của mã tôi nên đặt vào nó, và khi tôi nên có một?
Là gì __main__.py
file cho, những gì sắp xếp của mã tôi nên đặt vào nó, và khi tôi nên có một?
Câu trả lời:
Thông thường, một chương trình Python được chạy bằng cách đặt tên tệp .py trên dòng lệnh:
$ python my_program.py
Bạn cũng có thể tạo một thư mục hoặc zipfile chứa đầy mã và bao gồm a __main__.py
. Sau đó, bạn có thể chỉ cần đặt tên thư mục hoặc zipfile trên dòng lệnh và nó __main__.py
sẽ tự động thực thi :
$ python my_program_dir
$ python my_program.zip
# Or, if the program is accessible as a module
$ python -m my_program
Bạn sẽ phải tự quyết định xem ứng dụng của bạn có thể hưởng lợi từ việc được thực thi như thế này hay không.
Lưu ý rằng một __main__
mô-đun thường không đến từ một __main__.py
tập tin. Nó có thể, nhưng nó thường không. Khi bạn chạy một tập lệnh như thế python my_program.py
, tập lệnh sẽ chạy dưới dạng __main__
mô-đun thay vì my_program
mô-đun. Điều này cũng xảy ra đối với các mô-đun chạy như python -m my_module
, hoặc theo một số cách khác.
Nếu bạn thấy tên __main__
trong thông báo lỗi, điều đó không nhất thiết có nghĩa là bạn nên tìm kiếm một __main__.py
tệp.
python3 program_dir
và nó chạy __init__.py
.
python3 dir
chạy __main__.py
nhưng không __init__.py
, trong khi python3 -m dir
chạy cả hai.
__main__.py
đó đã kích hoạt việc nhập__init__.py
__main__.py
tập tin cho là gì?Khi tạo một mô-đun Python, thông thường để làm cho mô-đun thực thi một số chức năng (thường được chứa trong một main
chức năng) khi chạy như là điểm vào của chương trình. Điều này thường được thực hiện với thành ngữ phổ biến sau được đặt ở dưới cùng của hầu hết các tệp Python:
if __name__ == '__main__':
# execute only if run as the entry point into the program
main()
Bạn có thể nhận được cùng một ngữ nghĩa cho gói Python __main__.py
. Đây là lời nhắc shell linux $
, nếu bạn không có Bash (hoặc shell Posix khác) trên Windows, chỉ cần tạo các tệp này demo/__<init/main>__.py
với nội dung ở giữa EOF
s:
$ mkdir demo
$ cat > demo/__init__.py << EOF
print('demo/__init__.py executed')
def main():
print('main executed')
EOF
$ cat > demo/__main__.py << EOF
print('demo/__main__.py executed')
from __init__ import main
main()
EOF
(Trong trình bao Posix / Bash, bạn có thể thực hiện các thao tác trên mà không cần << EOF
s và kết thúc EOF
bằng cách nhập Ctrl+ D, ký tự cuối tệp, ở cuối mỗi lệnh mèo)
Và bây giờ:
$ python demo
demo/__main__.py executed
demo/__init__.py executed
main executed
Bạn có thể rút ra điều này từ tài liệu. Các tài liệu nói:
__main__
- Môi trường tập lệnh cấp cao nhất
'__main__'
là tên của phạm vi mà mã cấp cao nhất thực thi. Một mô-đun__name__
được đặt bằng với'__main__'
khi đọc từ đầu vào tiêu chuẩn, tập lệnh hoặc từ dấu nhắc tương tác.Một mô-đun có thể khám phá xem nó có chạy trong phạm vi chính hay không bằng cách kiểm tra chính nó
__name__
, điều này cho phép một thành ngữ chung để thực thi mã có điều kiện trong một mô-đun khi nó chạy như một tập lệnh hoặcpython -m
không phải khi được nhập:if __name__ == '__main__': # execute only if run as a script main()
Đối với một gói, hiệu ứng tương tự có thể đạt được bằng cách bao gồm một
__main__.py
mô-đun, nội dung của nó sẽ được thực thi khi mô-đun được chạy với-m
.
Bạn cũng có thể đóng gói tệp này thành một tệp duy nhất và chạy nó từ dòng lệnh như thế này - nhưng lưu ý rằng các gói được nén không thể thực thi các gói con hoặc mô hình con làm điểm vào:
$ python -m zipfile -c demo.zip demo/*
$ python demo.zip
demo/__main__.py executed
demo/__init__.py executed
main() executed
__main__.py
được sử dụng cho các chương trình python trong các tệp zip. Các__main__.py
tập tin sẽ được thực hiện khi các tập tin zip trong chạy. Ví dụ: nếu tệp zip là như vậy:
test.zip
__main__.py
và nội dung của __main__.py
là
import sys
print "hello %s" % sys.argv[1]
Sau đó, nếu chúng ta chạy python test.zip world
chúng tôi sẽ hello world
ra ngoài.
Vì vậy, __main__.py
tệp chạy khi python được gọi trên một tệp zip.
Bạn tạo __main__.py
trong yourpackage
để làm cho nó thực thi như sau:
$ python -m yourpackage
-m
hoạt động nếu chỉ có chương trình có thể truy cập dưới dạng mô-đun, nếu không bạn có thể sử dụng python <yourpackage>
LƯU Ý: không có -m
tùy chọn
package
gì?
python -m <yourproject>
không hoạt động, -m
là một tùy chọn dự phòng, nhưng python <yourpackage>
hoạt động tốt.
a
và giả sử tập lệnh a/b/c/__main__.py
... python -m b.c
sẽ thực thi từ thư mục a
và việc nhập tập lệnh chính sẽ liên quan đến a
. Nhưng python b/c
sẽ thực thi từ phạm vi nhập của dir c
và do đó, bất kỳ nhập nào như trong tập lệnh chính import b.d
sẽ thất bại.
python -m program_dir
vàpython program_dir
một chút khác biệt: cái sau không bao giờ chạy__init__.py
trong thư mục (nếu có).