我正在创建一个多级包,结构看起来像这样
test.py
main_package/
sub_package1/
tables/
table1.json
table2.json
__init__.py # empty
lib1.py
sub_package2/
tables/
table21.json
table22.json
__init__.py # empty
lib2
__init__.py # empty
common1.py
common2.py
master_table.json
目前,所有__init__.py
都是空的。
main_package / master_table.json的内容
{
"group1": {
"base": "sub_package1/tables",
"files": [
"table1.json",
"table2.json"
]
},
"group2": {
"base": "sub_package2/tables",
"files": [
"table21.json",
"table22.json"
]
}
}
在main_package / common2.py
中import json
class DataTables(object):
# codes for making this class a Singleton omitted
...
def _process_table(self, table)
...
# will be called from __init__
def _read_tables(self):
# the following line throws IOError: file not found
table_list = json.load(open('master_table.json'))
for s, desc in table_list.items():
for f in desc['files']:
fname = desc['base'] + '/' + f
# this line also expected to throw IOError
self._process_table(json.load(open(fname)))
在test.py中
from main_package.common2 import DataTables
test = DataTables()
正如预期的那样,DataTable._read_tables()失败,因为解释器在test.py所在的目录中找不到master_table.json。如果common2.py直接运行,代码运行正常。
问题是如何以灵活的方式纠正这个问题,无论目录结构test.py实际位于何处(即在另一个目录结构中)。
另一个问题是我如何测试,例如,lib1.py通过直接运行它来取决于common1.py中列出的函数?
lib1.py中的(这不起作用)
from ..common1 import foo
def this_is_in_lib1()
...
foo()
...
ValueError: Attempted relative import in non-package
同时修改导入
from main_package.common1 import foo
从test.py运行它就像这样工作
from main_package.sub_package.lib1 import this_is_on_lib1
this_is_in_lib1()
由于
答案 0 :(得分:1)
模块具有__file__
属性,告诉您.py文件的路径。通常,
table1 = json.load(open(os.path.join(os.path.dirname(__file__), 'table1.json)))
在该目录中的.py文件中就足够了。
答案 1 :(得分:0)
关于直接运行lib1.py
的第二个问题,请不要这样做。不要在包装内使用任意入口点。您的包将由客户端代码导入,例如test.py
中的代码。导入包并从那里进行测试,如果无法识别某个内部模块,则需要在相应的__init__.py
内导入其名称。或者将测试作为子包,只使用测试子包中的常用相对路径。