2011-01-23 43 views
20

tôi đã bằng cách nào đó ngạc nhiên bởi hành vi sau đây:__main__ và Phạm vi trong python

def main(): 
    print "%s" % foo 

if __name__ == "__main__": 
    foo = "bar" 
    main() 

tức là chức năng mô-đun có quyền truy cập vào kèm theo biến trong __main__. Giải thích cho nó là gì?

+3

Không có phạm vi '__main__'. Có một 'if' xảy ra để so sánh một biến xảy ra được gọi là' __name__' với một cái gì đó xảy ra là chuỗi ký tự '' __main __ "'. – delnan

+0

@delnan: '__main__' là một mô-đun và mỗi mô-đun có phạm vi được liên kết. Hãy thử 'import __main__; gõ (__ main __) 'trong trình thông dịch (không phải trong IPython). –

+0

@Sven: Tôi biết. OP nên biết tại một số điểm. Nhưng có vẻ như với tôi OP thay vì bối rối nếu các câu lệnh với các phần của điều kiện và nghĩ rằng 'if' giới thiệu một phạm vi mới - đó sẽ là một vấn đề bức xúc hơn. (Phải thừa nhận rằng, "Không có phạm vi' __main__' là gây hiểu lầm, nói đúng) – delnan

Trả lời

20

Các biến trong phạm vi toàn cầu mô-đun hiện tại được hiển thị ở mọi nơi trong mô-đun - quy tắc này cũng giữ cho mô-đun __main__.

Từ Guido's tutorial:

Bất cứ lúc nào trong quá trình thực hiện, có ít nhất ba phạm vi lồng nhau có không gian tên là truy cập trực tiếp:

  • phạm vi trong cùng, mà là tìm kiếm đầu tiên, chứa các địa phương Tên
  • phạm vi của bất kỳ chức năng kèm theo nào, được tìm kiếm bắt đầu với phạm vi bao gồm gần nhất, chứa tên không phải cục bộ, nhưng cũng không phải là toàn cục
  • tiếp theo-to-cuối cùng phạm vi chứa tên toàn cầu module hiện tại của
  • phạm vi ngoài cùng (đã tìm kiếm cuối cùng) là không gian tên có chứa built-in tên
+0

'__main__' * module *? – user225312

+0

@AA: Kịch bản chính được Python xử lý như một mô đun có tên '__main__'. Bạn thậm chí có thể thực hiện' import __main__' (nhưng thường là một ý tưởng tồi). –

6

foo là một biến toàn cục mô-đun (không có trong bất kỳ hàm nào). Tất cả các phạm vi trong mô-đun có thể truy cập nó.

2

Trong python có phạm vi toàn cầu, và các chức năng có phạm vi riêng của họ. Vì vậy, nó bạn xác định foo dưới tên == chính, nó trong phạm vi toàn cầu. Ngoài ra, nó không phải là một sai lầm khi sử dụng một biến chưa được khai báo, trong một hàm, nếu nó sẽ được khai báo bởi thời gian hàm sẽ được gọi.

4

Điều ở đây là:

if __name__ == "__main__": 
    foo = "bar" 

định nghĩa một biến toàn cục có tên foo trong kịch bản đó. vì vậy bất kỳ chức năng nào của mô-đun đó sẽ có quyền truy cập vào nó.

Đoạn mã được liệt kê ở trên là toàn cục cho mô-đun và không nằm trong bất kỳ hàm nào.