2012-12-28 24 views
8

thể trùng lặp:
Dynamic module import in PythonNhập tập tin sử dụng chuỗi như tên

tôi có ý định làm một bộ các tập tin tại một thời điểm nào sớm, và cách tốt nhất để tổ chức nó là phải có một danh sách, danh sách đó sẽ ở trên cùng của một tập tin, và sau khi nó sẽ đến một số lượng vô lý của mã để xử lý những gì mà danh sách kiểm soát và cách nó hoạt động. Tôi đang tìm để viết danh sách nói chỉ một lần, và nói danh sách là danh sách các thư mục và tên tập tin ở định dạng này:

[(folder/filename, bool, bool, int), (folder/filename, bool, bool, int)] 

Như bạn thấy, folder/filename đều giống nhau (loại). Tên tệp là tên thư mục có số .py khi kết thúc, nhưng nhập XXX, bạn không cần nhập XXX.py, vì vậy, tôi không thấy điều này gây ra sự cố.

Vấn đề tôi đang phải đối mặt là nhập khẩu sử dụng phương pháp này ...

for (testName, auto, hardware, bit) in testList: 
    print(testName) 
    paths = "\\" + testName 
    print paths 
    addpath(paths) 
    sys.modules[testName] = testName # One of a few options I've seen suggested on the net 
    print("Path Added") 
    test = testName + ".Helloworld()" 
    eval(test) 

Vì vậy cho mỗi bài kiểm tra tôi có, in tên, lắp ráp một chuỗi chứa đường dẫn ("\\testName"), ví dụ này , in đường dẫn kiểm tra, sau đó thêm đường dẫn vào danh sách (sys.path.append(path)), sau đó in để xác nhận nó xảy ra, sau đó lắp ráp một chuỗi sẽ được thực hiện bởi eval cho mô-đun chính thử nghiệm và cuối cùng đánh giá nó.

Như bạn có thể thấy, tôi hiện đang có danh sách hàng nhập ở trên cùng. Tôi không thể nhập đơn giản testName (nội dung của testName là tên của mô-đun mà tôi muốn nhập), vì nó sẽ cố gắng tìm một mô-đun có tên là testName, không phải là mô-đun được gọi là nội dung của testName.

Tôi đã xem một vài ví dụ về việc điều này đã được thực hiện ở đâu, nhưng không thể tìm thấy bất kỳ hoạt động nào trong hoàn cảnh của tôi. Nếu ai đó theo nghĩa đen có thể ném một đoạn mã mà nó sẽ là tuyệt vời.

Tôi cũng yêu cầu tôi không bị treo, rút ​​hoặc không sử dụng eval, nó được sử dụng trong một môi trường được kiểm soát (danh sách mà chu kỳ của nó nằm trong tệp .py, vì vậy không " người dùng cuối "nên gây rối với nó).

+0

Lưu ý rằng thụt đầu dòng là chính xác trong ST, đối với một số lý do tôi nghĩ rằng trang web này chỉ không thích phân tích cú pháp văn bản của tôi một cách chính xác :( – XtrmJosh

+1

Không sử dụng các tab nhưng không gian cho indentation. –

+2

Python đã có một chặng đường quản lý tập hợp lớn các tệp '.py' mà bạn có thể muốn nhập, để hiểu các thư mục và thư mục con, cho phép bạn xử lý việc nhập tương đối, thực hiện đặt tên đúng cách, v.v. Nó được gọi là [gói] (http: // docs. python.org/2/tutorial/modules.html#packages) Có lý do nào bạn không muốn sử dụng không? – katrielalex

Trả lời

24

Không chắc chắn nếu tôi hiểu tất cả mọi thứ một cách chính xác, nhưng bạn có thể nhập một mô-đun tự động sử dụng __import__:

mod = __import__(testName) 
mod.HelloWorld() 

Sửa: Tôi đã không nhận thức được rằng việc sử dụng __import__ được nản chí bởi các tài liệu python cho mã người dùng: __import__ documentation (như ghi nhận của Bakuriu)

này cũng nên làm việc và sẽ được coi là phong cách tốt hơn:

mod = importlib.import_module(testName) 
mod.HelloWorld() 
+0

Thật tuyệt vời, cảm ơn một tấn cho điều này, đã dành hơn một giờ cọ rửa thông tin về nó, tôi quản lý để viết __import __ (testName) trước đó, nhưng không nhận ra tôi đã gán phản hồi cho một mô-đun hoặc chúng tôi, may mắn thay tất cả các chức năng của tôi sẽ được đặt tên Test trong tất cả các tệp, vì vậy tôi có thể gọi mod.Test() từ bây giờ. – XtrmJosh

+0

@XtrmJosh bạn có thấy câu trả lời khác không? '__import__' là chi tiết triển khai; bạn nên sử dụng 'importlib' (hoặc' imp' nếu bạn không quan tâm đến khả năng tương thích Python 3.x). – katrielalex

16
  1. Không bao giờ, không bao giờ, luôn gây rối với sys.modules trực tiếp nếu bạn không biết chính xác mình đang làm gì.
  2. Có rất nhiều cách để làm những gì bạn muốn:
    1. Bản build-in __import__ chức năng
    2. Sử dụng imp.load_module
    3. Sử dụng importlib.import_module

Tôi muốn tránh sử dụng __import__ trực tiếp và truy cập importlib.import_module (cũng được đề xuất ở cuối tài liệu của __import__).

+1

Điều này là dành cho 'import moduleName' trong đó moduleName là chuỗi. Làm thế nào về 'từ nhập khẩu moduleName *'? –

+2

@NamGVU cố gắng nhập mô-đun như trên và sau đó: cập nhật 'globals(). (Mô-đun .__ dict __)' – Bakuriu

+0

Làm việc như một sự quyến rũ. Cảm ơn bạn! –

0

Thêm đường dẫn nơi mô-đun nằm ở sys.path. Nhập khẩu mô-đun bằng hàm __import__ chấp nhận biến chuỗi làm tên mô-đun.

import sys 
sys.path.insert(0, mypath) # mypath = path of module to be imported 
imported_module = __import__("string_module_name") # __import__ accepts string 
imported_module.myfunction() # All symbols in mymodule are now available normally 
Các vấn đề liên quan