2012-07-09 7 views
13

Tôi đã là nguồn gốc cấu trúc mã sauPython gói nhập từ thư mục cha

/testapp/ 
/testapp/__init__.py 
/testapp/testmsg.py 
/testapp/sub/ 
/testapp/sub/__init__.py 
/testapp/sub/testprinter.py 

nơi testmsg định nghĩa sau đây liên tục:

MSG = "Test message" 

sub/testprinter.py:

import testmsg 

print("The message is: {0}".format(testmsg.MSG)) 

Nhưng tôi 'm nhận được ImportError: No module named testmsg

Không nên hoạt động từ cấu trúc gói? Tôi không thực sự muốn mở rộng sys.path trong mỗi submodule và tôi thậm chí không muốn sử dụng nhập khẩu tương đối.

Tôi đang làm gì sai ở đây?

+0

Cách bạn thực thi mã? –

+0

@SimeonVisser chạy 'python sub/testprinter.py', nhưng cũng' python testprinter.py' trong thư mục 'sub' không hoạt động. –

Trả lời

8

Tất cả đều phụ thuộc vào kịch bản bạn chạy. Đường dẫn của tập lệnh đó sẽ được thêm vào đường dẫn tìm kiếm của python một cách tự động.

Làm cho nó cấu trúc sau:

TestApp/ 
TestApp/README 
TestApp/LICENSE 
TestApp/setup.py 
TestApp/run_test.py 
TestApp/testapp/__init__.py 
TestApp/testapp/testmsg.py 
TestApp/testapp/sub/ 
TestApp/testapp/sub/__init__.py 
TestApp/testapp/sub/testprinter.py 

Sau đó chạy TestApp/run_test.pyđầu tiên:

from testapp.sub.testprinter import functest ; functest() 

Sau đó TestApp/testapp/sub/testprinter.py có thể làm:

from testapp.testmsg import MSG 
print("The message is: {0}".format(testmsg.MSG)) 

Thêm gợi ý tốt here;

+0

có thể phụ thuộc vào thực tế là tôi không tạo tệp setup.py? Những gì tôi có nghĩa là tôi theo cấu trúc gói python nhưng tôi đã không tạo ra phương pháp cài đặt, giả sử nó cũng có thể làm việc mà không cần phải 'setup.py install' nó. –

+0

@CodeShining, không có vấn đề gì. Tôi chỉ đưa 'setup.py' vào ví dụ để làm rõ. Điều thực sự quan trọng, như tôi đã nói trong đoạn đầu tiên của câu trả lời, là ** tệp nào bạn đang chạy ở vị trí đầu tiên **. Nếu bạn bắt đầu (chạy) một tập tin bên trong gói, nó sẽ không thấy gói. Vì vậy, đó là một thực hành tốt để có kịch bản chính của bạn (một trong những bạn ** chạy **) bên ngoài gói. – nosklo

6

Sử dụng nhập khẩu tương đối như dưới đây

from .. import testmsg 
+0

nhưng là một gói không nên hoạt động như mong đợi? Tôi sẽ không sử dụng tương đối nếu nó dự kiến ​​sẽ làm việc –

+0

CodeShining, xem xét quyết định của Dido cho python 3.5 PEP-328 cho tiêu chuẩn. [link] (http://www.python.org/dev/peps/pep-0328/#guido-s-decision) –

4

Câu hỏi này có câu trả lời - nhập khẩu năng động:

How to import a python file in a parent directory

import sys 
sys.path.append(path_to_parent) 
import parent.file1 

Đây là điều mà tôi thực hiện để nhập khẩu bất cứ điều gì. Tất nhiên, bạn vẫn phải sao chép tập lệnh này vào các thư mục cục bộ, nhập nó và use đường dẫn bạn muốn.

import sys 
import os 

# a function that can be used to import a python module from anywhere - even parent directories 
def use(path): 
    scriptDirectory = os.path.dirname(sys.argv[0]) # this is necessary to allow drag and drop (over the script) to work 
    importPath = os.path.dirname(path) 
    importModule = os.path.basename(path) 
    sys.path.append(scriptDirectory+"\\"+importPath)  # Effing mess you have to go through to get python to import from a parent directory 

    module = __import__(importModule) 
    for attr in dir(module): 
     if not attr.startswith('_'): 
      __builtins__[attr] = getattr(module, attr)