Tại sao Python chạy mô-đun của tôi khi tôi nhập nó và làm cách nào để dừng nó?


171

Tôi có một chương trình Python tôi đang xây dựng có thể chạy theo một trong hai cách: cách đầu tiên là gọi "python main.py" nhắc người dùng nhập liệu một cách thân thiện và sau đó chạy đầu vào của người dùng thông qua chương trình. Một cách khác là gọi "python batch.py -file- " sẽ chuyển qua tất cả các tập hợp đầu vào thân thiện và chạy toàn bộ giá trị đầu vào của tệp thông qua chương trình trong một lần.

Vấn đề là khi tôi chạy "batch.py", nó sẽ nhập một số biến / phương thức / etc từ "main.py" và khi nó chạy mã này:

import main

ở dòng đầu tiên của chương trình, nó ngay lập tức bị lỗi vì nó cố chạy mã trong "main.py".

Làm cách nào tôi có thể ngăn Python chạy mã có trong mô-đun "chính" mà tôi đang nhập?

Câu trả lời:


249

Bởi vì đây chỉ là cách Python hoạt động - các từ khóa như classkhông phảidefkhai báo . Thay vào đó, chúng là những tuyên bố trực tiếp thực sự được thực thi. Nếu chúng không được thực thi, mô-đun của bạn sẽ .. trống :-)

Dù sao, cách tiếp cận thành ngữ là:

# stuff to run always here such as class/def
def main():
    pass

if __name__ == "__main__":
   # stuff only to run when not called via 'import' here
   main()

Xem gì là if __name__ == "__main__"gì?

Tuy nhiên, nó yêu cầu kiểm soát nguồn đối với mô-đun đang được chỉnh sửa import.

Chúc mừng mã hóa.


1
chỉ để xác nhận, nhận xét của bạn "công cụ chỉ chạy khi không được gọi thông qua 'nhập' ở đây" ngụ ý các lệnh được viết dưới hàm main (), phải không? Hoặc nó không quan trọng ??
Goldname

@Goldname Mã bên trong câu lệnh if sẽ không được chạy khi được nhập, nhưng chính hàm này đã được xác định và sẵn sàng để sử dụng ngay cả khi nhập. Mô-đun này sẽ chỉ thực thi chức năng chính khi chạy và không thực thi nó nếu được nhập. Tất cả phụ thuộc vào những gì bạn muốn làm. Nếu bạn không cần các lệnh bên trong chính ở nơi khác, bằng mọi cách, hãy viết chúng bên trong if. Nhưng với tôi nó trông gọn gàng hơn.
Felix

51

Do cách thức hoạt động của Python, nó cần thiết để chạy các mô-đun của bạn khi nó nhập chúng.

Để ngăn không cho mã trong mô-đun được thực thi khi được nhập, nhưng chỉ khi chạy trực tiếp, bạn có thể bảo vệ nó bằng cách này if:

if __name__ == "__main__":
    # this won't be run when imported

Bạn có thể muốn đặt mã này vào một main()phương thức, để bạn có thể thực thi tệp trực tiếp hoặc nhập mô-đun và gọi main(). Ví dụ, giả sử đây là trong tập tin foo.py.

def main():
    print "Hello World"

if __name__ == "__main__":
    main()

Chương trình này có thể được chạy bằng cách đi python foo.pyhoặc từ một tập lệnh Python khác:

import foo

...

foo.main()

12

Sử dụng if __name__ == '__main__'thành ngữ - __name__là một biến đặc biệt có giá trị là '__main__'nếu mô-đun đang được chạy dưới dạng tập lệnh và tên mô-đun nếu được nhập. Vì vậy, bạn sẽ làm một cái gì đó như

# imports
# class/function definitions
if __name__ == '__main__':
    # code here will only run when you invoke 'python main.py'

4

Thật không may, bạn không. Đó là một phần trong cách cú pháp nhập hoạt động và điều quan trọng là nó làm như vậy - hãy nhớ defthực sự là một cái gì đó được thực thi, nếu Python không thực hiện nhập, bạn sẽ bị kẹt mà không có chức năng.

Vì bạn có thể có quyền truy cập vào tệp, tuy nhiên, bạn có thể có thể xem và xem nguyên nhân gây ra lỗi. Có thể sửa đổi môi trường của bạn để ngăn lỗi xảy ra.


1
Lưu ý: nếu không có cách nào sửa đổi môi trường để có thể ngăn ngừa lỗi, có lẽ bạn nên sử dụng một mô-đun khác
cwallenpoole

4

Đặt mã bên trong một hàm và nó sẽ không chạy cho đến khi bạn gọi hàm. Bạn nên có một chức năng chính trong của bạn main.py. với tuyên bố:

if __name__ == '__main__':
  main()

Sau đó, nếu bạn gọi python main.pycác main()chức năng sẽ chạy. Nếu bạn nhập main.py, nó sẽ không. Ngoài ra, bạn có lẽ nên đổi tên main.pythành một cái gì đó khác cho rõ ràng.


3

Có một đề xuất tăng cường Python PEP 299 nhằm mục đích thay thế if __name__ == '__main__':thành ngữ bằng def __main__:, nhưng nó đã bị từ chối. Đây vẫn là một bài đọc tốt để biết những gì cần lưu ý khi sử dụng if __name__ = '__main__':.


2

Bạn có thể viết "main.py" của mình như thế này:

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()

-1

Mặc dù bạn không thể sử dụng importmà không chạy mã; có một cách khá nhanh chóng để bạn có thể nhập các biến của mình; bằng cách sử dụng numpy.savez, lưu trữ các biến dưới dạng mảng numpy trong tệp .npz. Sau đó, bạn có thể tải các biến bằng cách sử dụng numpy.load.

Xem mô tả đầy đủ trong tài liệu scipy

Xin lưu ý đây chỉ là trường hợp cho các biến và mảng của biến chứ không phải cho các phương thức, v.v.


-4

Hãy thử chỉ nhập các chức năng cần thiết từ main.py? Vì thế,

from main import SomeFunction

Có thể là bạn đã đặt tên cho một hàm trong batch.py ​​giống như một hàm trong main.py và khi bạn nhập main.txt, chương trình sẽ chạy hàm main.txt thay vì hàm batch.py; làm như trên nên khắc phục điều đó. Tôi hi vọng.


Ít nhất là trên Windows, nó không.
Martín Coll

2
import mainKHÔNG nhập mọi thứ từ chính vào không gian tên hiện tại. Nó chỉ thêm một mainký hiệu duy nhất trong không gian tên hiện tại, vì vậy va chạm không thể xảy ra.
lại
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.