【问题标题】:Multi level packages, file paths, and inter sub-package/module imports多级包、文件路径和子包/模块间导入
【发布时间】:2018-04-21 20:32:24
【问题描述】:

我正在创建一个多级包,其结构如下所示

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()

谢谢

【问题讨论】:

    标签: python python-2.7 ipython


    【解决方案1】:

    模块有一个__file__ 属性,告诉您.py 文件的路径。通常,

    table1 = json.load(open(os.path.join(os.path.dirname(__file__), 'table1.json)))
    

    在该目录中的 .py 文件中就足够了。

    【讨论】:

      【解决方案2】:

      关于直接运行lib1.py 的第二个问题,不要那样做。不要在包中使用任意入口点。您的包将由客户端代码导入,例如test.py 中的代码。导入包并从那里进行测试,如果无法识别某些内部模块,则需要在相应的__init__.py 中导入其名称。或者将测试作为一个子包,并在测试子包中使用通常的相对路径。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-25
        • 2021-01-06
        • 2011-12-13
        • 1970-01-01
        • 2019-01-27
        • 2015-02-28
        • 2018-01-31
        相关资源
        最近更新 更多