2009-11-28 37 views
7

Tôi có một số mã mà tải một tập tin cấu hình mặc định và sau đó cho phép người dùng để cung cấp các file Python của mình như cấu hình thêm bổ sung hoặc ghi đè các giá trị mặc định:Python: execfile từ thư mục làm việc của tệp khác?

# foo.py 

def load(cfg_path=None): 
    # load default configuration 
    exec(default_config) 

    # load user-specific configuration 
    if cfg_path: 
     execfile(cfg_path) 

Có một vấn đề, mặc dù: execfile() thực hiện chỉ thị trong tệp được chỉ định bởi cfg_path như thể nó nằm trong thư mục làm việc của foo.py, không phải thư mục làm việc của riêng nó. Do đó, import chỉ thị có thể không thành công nếu tệp cfg_path, chẳng hạn như from m import x trong đó m là một mô-đun trong cùng một thư mục với tên cfg_path.

Làm cách nào để execfile() từ thư mục hoạt động của đối số của nó hoặc đạt được kết quả tương đương? Ngoài ra, tôi đã nói rằng execfile không còn được dùng trong Python 3 và tôi nên sử dụng exec, vì vậy nếu có cách nào tốt hơn tôi nên làm điều này, tôi là tất cả các tai.

Lưu ý: Tôi không nghĩ rằng các giải pháp chỉ thay đổi thư mục hoạt động là chính xác. Điều đó sẽ không đặt các mô-đun đó vào đường dẫn tìm kiếm mô-đun của trình thông dịch, theo như tôi có thể nói.

Trả lời

7

os.chdir cho phép bạn thay đổi thư mục làm việc theo ý muốn (bạn có thể trích xuất thư mục làm việc của cfg_path với os.path.dirname); trước tiên hãy chắc chắn lấy thư mục hiện tại với os.getcwd nếu bạn muốn khôi phục thư mục đó khi bạn hoàn thành việc thực hiện cfg_path.

Python 3 thực sự loại bỏ execfile (ưu tiên một chuỗi nơi bạn đọc tệp, compile nội dung, sau đó exec chúng), nhưng bạn không cần lo lắng về điều đó, nếu bạn hiện đang viết mã bằng Python 2.6, nguồn số 2to3 cho các giao dịch dịch nguồn với tất cả điều này suôn sẻ và liền mạch.

Chỉnh sửa: OP cho biết, trong nhận xét rằng execfile khởi chạy quy trình riêng và không tôn trọng thư mục làm việc hiện tại. Đây là sai sự thật, và đây là một ví dụ cho thấy rằng nó là:

import os 

def makeascript(where): 
    f = open(where, 'w') 
    f.write('import os\nprint "Dir in file:", os.getcwd()\n') 
    f.close() 

def main(): 
    where = '/tmp/bah.py' 
    makeascript(where) 
    execfile(where) 
    os.chdir('/tmp') 
    execfile(where) 

if __name__ == '__main__': 
    main() 

Chạy này trên máy tính của tôi sản xuất ra như:

Dir in file: /Users/aleax/stko 
Dir in file: /private/tmp 

cho thấy rõ ràng rằng execfilekhông tiếp tục sử dụng các thư mục làm việc đó là đặt tại thời điểm execfile thực hiện. (Nếu tệp được thực hiện thay đổi thư mục làm việc, nó sẽ được phản ánh sau khi trả về execfile - chính xác vì mọi thứ diễn ra trong cùng một quá trình!). Vì vậy, bất kỳ vấn đề nào mà OP vẫn đang quan sát là không phải gắn với thư mục làm việc hiện tại (thật khó để chẩn đoán chúng thực sự là gì, mà không nhìn thấy mã và chi tiết chính xác của các vấn đề được quan sát ;-).

+0

Cảm ơn câu trả lời của bạn. Thật không may, điều này dường như không làm việc cho tôi. 'execfile()' dường như đang khởi chạy một tiến trình hoàn toàn mới với thư mục làm việc riêng của nó, nó không giống như thư mục tôi đang khởi chạy. –

+0

Không, @Kyle, 'execfile' không khởi chạy một quá trình riêng biệt, và nó ** không tôn trọng thư mục làm việc hiện tại. Chỉnh sửa câu trả lời của tôi để hiển thị một ví dụ đơn giản chứng minh rằng bạn đã sai. –

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