__Main__.py là gì?


326

Là gì __main__.pyfile 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:


320

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__.pysẽ 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__.pytậ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_programmô-đ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__.pytệp.


22
Tôi tìm thấy python -m program_dirpython program_dirmột chút khác biệt: cái sau không bao giờ chạy __init__.pytrong thư mục (nếu có).
brk

5
@brk: Điều đó dường như không phải là trường hợp bây giờ. Tôi chỉ cần thử python3 program_dirvà nó chạy __init__.py.
mk12

@ mk12 Tôi vừa thử, tôi có thể xác nhận kết quả của @ brk: python3 dirchạy __main__.pynhưng không __init__.py, trong khi python3 -m dirchạy cả hai.
Marcello Romani

1
@ mk12 Có lẽ bạn đã có một số mã trong __main__.pyđó đã kích hoạt việc nhập__init__.py
wim

100

Các __main__.pytậ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 mainchứ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>__.pyvới nội dung ở giữa EOFs:

$ 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 << EOFs và kết thúc EOFbằ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ặc python -mkhô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__.pymô-đun, nội dung của nó sẽ được thực thi khi mô-đun được chạy với -m.

Đã nén

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

31

__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

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 worldra ngoài.

Vì vậy, __main__.pytệp chạy khi python được gọi trên một tệp zip.


23

Bạn tạo __main__.pytrong yourpackageđể làm cho nó thực thi như sau:

$ python -m yourpackage

1
-mhoạ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ó -mtùy chọn
Benyamin Jafari

1
@BenyaminJafari không thể viết chương trình Python dòng lệnh không thể truy cập dưới dạng mô-đun . Có lẽ bạn có ý packagegì?
anatoly techtonik

1
Khi chúng ta tạo gói Python chứa .py chính , để chạy nó python -m <yourproject>không hoạt động, -mlà một tùy chọn dự phòng, nhưng python <yourpackage>hoạt động tốt.
Benyamin Jafari

@BenyaminJafari Cờ -m không tạo ra sự khác biệt trong một số trường hợp. Thực thi từ thư mục avà giả sử tập lệnh a/b/c/__main__.py... python -m b.csẽ thực thi từ thư mục avà việc nhập tập lệnh chính sẽ liên quan đến a. Nhưng python b/csẽ thực thi từ phạm vi nhập của dir cvà do đó, bất kỳ nhập nào như trong tập lệnh chính import b.dsẽ thất bại.
MikeCPT

14

Nếu tập lệnh của bạn là một thư mục hoặc tệp ZIP chứ không phải là một tệp python, __main__.pysẽ được thực thi khi "tập lệnh" được truyền dưới dạng đối số cho trình thông dịch python.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.