2009-03-03 36 views
46

Giả sử tôi có hai mô-đun:Cách lấy tên tệp của mô-đun __main__ bằng Python?

a.py:

import b 
print __name__, __file__ 

b.py:

print __name__, __file__ 

Tôi chạy "a.py" tập tin. in này:

b  C:\path\to\code\b.py 
__main__ C:\path\to\code\a.py 

Câu hỏi: làm thế nào để có được đường dẫn đến __main__ mô-đun ("a.py" trong trường hợp này) từ bên trong thư viện "b.py"?

Trả lời

58
import __main__ 
print __main__.__file__ 
+1

Gọn gàng! Quan trọng để nhận ra rằng người ta cần nhập __main__ - Tôi đã đoán ngẫu nhiên và thực sự đã thử dòng thứ hai, nhưng nó không thành công - bây giờ tôi biết tại sao. –

+17

'__main__' không phải lúc nào cũng có thuộc tính' __file__'. – jfs

+0

Vâng, sẽ rất tuyệt nếu câu trả lời có thể được cập nhật để đề cập đến điều đó. –

27

lẽ điều này sẽ làm các trick:

import sys 
from os import path 
print path.abspath(sys.modules['__main__'].__file__) 

Lưu ý rằng, vì sự an toàn, bạn nên kiểm tra xem các mô-đun __main__ có một thuộc tính __file__. Nếu nó tự động tạo ra, hoặc là chỉ được chạy trong python console tương tác, nó sẽ không có một __file__:

python 
>>> import sys 
>>> print sys.modules['__main__'] 
<module '__main__' (built-in)> 
>>> print sys.modules['__main__'].__file__ 
AttributeError: 'module' object has no attribute '__file__' 

Một hasattr đơn giản() kiểm tra sẽ làm các trick để bảo vệ chống lại kịch bản 2 nếu đó là một khả năng trong ứng dụng của bạn.

+0

Có - cảm ơn! –

+0

Wunderbar! Tôi rất vui vì tôi có thể giúp. Nếu điều này trả lời câu hỏi của bạn, bạn có phiền khi nhấn nút 'chấp nhận' trên câu hỏi không? :-) –

+0

Nếu bạn chỉnh sửa điều này để sử dụng kiểu "nhập __main__", tôi sẽ thay đổi lại thành được chấp nhận vì điều này chi tiết hơn so với câu trả lời được chấp nhận mới. –

14

Mã python bên dưới cung cấp chức năng bổ sung, bao gồm chức năng hoạt động liền mạch với py2exe thực thi.

Tôi sử dụng mã tương tự như thế này để tìm đường dẫn liên quan đến tập lệnh đang chạy, còn gọi là __main__. như một lợi ích bổ sung, nó hoạt động đa nền tảng bao gồm cả Windows.

import imp 
import os 
import sys 

def main_is_frozen(): 
    return (hasattr(sys, "frozen") or # new py2exe 
      hasattr(sys, "importers") # old py2exe 
      or imp.is_frozen("__main__")) # tools/freeze 

def get_main_dir(): 
    if main_is_frozen(): 
     # print 'Running from path', os.path.dirname(sys.executable) 
     return os.path.dirname(sys.executable) 
    return os.path.dirname(sys.argv[0]) 

# find path to where we are running 
path_to_script=get_main_dir() 

# OPTIONAL: 
# add the sibling 'lib' dir to our module search path 
lib_path = os.path.join(get_main_dir(), os.path.pardir, 'lib') 
sys.path.insert(0, lib_path) 

# OPTIONAL: 
# use info to find relative data files in 'data' subdir 
datafile1 = os.path.join(get_main_dir(), 'data', 'file1') 

Hy vọng rằng các mã ví dụ trên có thể cung cấp cái nhìn sâu sắc hơn về cách để xác định đường dẫn đến kịch bản chạy ...

+1

Nếu bạn thay đổi thư mục (với 'os.chdir') giữa khởi chạy kịch bản và gọi 'os.dirname (sys.argv [0])' kết quả là vô nghĩa. – RobM

+0

Tôi sử dụng để tạo mô-đun 'GLOBALS.py', ít nhất được nhập bởi tập lệnh chính, thực thi một cái gì đó giống như mã trên và lưu kết quả trong biến' MAINDIR', vì vậy tôi có thể truy cập 'GLOBALS.MAINDIR' từ bất kỳ mô-đun nào khác, mà không phải lo lắng về việc sử dụng 'os.chdir'. – Remi

+0

Nếu bạn muốn biết thư mục bắt đầu của tập lệnh và bạn cũng muốn sử dụng 'os.chdir()', bạn sẽ muốn lưu 'os.getcwd()' ban đầu. Kể từ khi người dùng đã được trên cửa sổ, tôi muốn chứng minh một cái gì đó mà vẫn sẽ làm việc trong bối cảnh của py2exe và đóng băng. – popcnt

1
import sys, os 

def getExecPath(): 
    try: 
     sFile = os.path.abspath(sys.modules['__main__'].__file__) 
    except: 
     sFile = sys.executable 
    return os.path.dirname(sFile) 

Chức năng này sẽ làm việc cho chương trình Python và Cython biên soạn.

6

Phương pháp khác sẽ là sử dụng sys.argv[0].

import os 
import sys 

main_file = os.path.realpath(sys.argv[0]) if sys.argv[0] else None 

sys.argv[0] sẽ là một chuỗi rỗng nếu Python được bắt đầu với -c hoặc nếu kiểm tra từ Python console.

Các vấn đề liên quan