【问题标题】:Python3 imports changesPython3 导入更改
【发布时间】:2018-08-24 15:59:28
【问题描述】:

我有一个模块使用在同一个包中定义的枚举。我想在本地运行它以进行自我测试,并从其他包中访问它,但我无法获取枚举的导入来处理这两种情况。

我在 sub 和 proj 目录中都尝试了一个空白的 _ _ init _ _.py(没有空格),没有明显的变化。

我尝试了 python -m 的变体但没有成功。

这是显示我的问题的最少代码:

    /my/proj
        |----sub
        |      |---e1.py
        |      |---one.py
        |      |---two.py
        |-p1.py
        |-p2.py

    ----
    $ cat /my/proj/sub/e1.py
    from enum import Enum
    class UsefulEnums(Enum):
        ZERO = 0

    ----
    $ cat /my/proj/sub/one.py
    from e1 import UsefulEnums as E
    def profound():
       print('The value of {} is {}'.format(E.ZERO.name, E.ZERO.value))
    if __name__ == '__main__':
       profound()

    /my/proj/sub$ python one.py
    The value of ZERO is 0
    ----
    $ cat /my/proj/sub/two.py
    # note the dot before the module name. No other change from one 
    from .e1 import UsefulEnums as E
    def profound():
       print('The value of {} is {}'.format(E.ZERO.name, E.ZERO.value))
    if __name__ == '__main__':
       profound()

    /proj/sub$ python two.py 
    Traceback (most recent call last):
      File "two.py", line 1, in <module>
        from .e1 import UsefulEnums as E
    ModuleNotFoundError: No module named '__main__.e1'; '__main__' is not a package

    ----
    $ cd /my/proj
    /my/proj$ cat p1.py
    import sub.one as a
    if __name__ == '__main__':
       a.profound()

    /my/proj$ python p1.py
    Traceback (most recent call last):
      File "p1.py", line 1, in <module>
        import sub.be1 as a
      File "/home/esmipau/delete_me/proj/sub/one.py", line 1, in <module>
        from e1 import UsefulEnums as E
    ModuleNotFoundError: No module named 'e1'
    ----
    /my/proj$ cat p2.py
    import sub.two as a
    if __name__ == '__main__':
       a.profound()

    /my/proj$ python p2.py
    The value of ZERO is 0

从“子”目录运行时,one.py 按预期工作,two.py 失败并出现“ModuleNotFoundError”错误,如上所述。 当在父代码中导入并从父目录运行时,two.py 现在可以工作,而 one.py 失败并出现不同的“ModuleNotFoundError”错误。 我想在“子”目录中有一个使用 e1.py 中定义的枚举的 three.py,它可以在本地运行以进行自我测试等,并且可以从不在同一目录中的外部模块中包含。

--- 编辑关闭作为重复的建议 --- 这与已建议的其他问题(例如Correct import and package structure now that __init__.py is optional)不同,因为我需要一种方法让一个模块在同一目录中导入另一个,无论该模块是在本地执行还是导入从另一个模块。

【问题讨论】:

标签: python-3.x


【解决方案1】:

我有类似的问题,这解决了它: 尝试像这样创建__init__ 文件:

import my.proj.sub.e1

然后在你想使用的文件中添加:

from my.proj.sub import UsefulEnums as E

【讨论】:

  • 这不适用于与 e1 相同的“子”目录中的模块,因此它们不能在独立或自检模式下运行。
【解决方案2】:

给定结构:

/proj
   |---/pkg
   |    |---> usefulEnums.py
   |    |---> usefulCode.py 
   |--> myProj.py 

我希望能够在自检模式下运行有用的代码.py,并且我想在 myProj 中导入和使用它。

$ cat proj/pkg/usefulEnums.py
from enum import Enum
class UsefulEnums(Enum):
    ZERO = 0 

$ cat proj/pkg/usefulCode.py
if __package__ is None:
    # works with python <path/>tcp.py
    from usefulEnums import UsefulEnums as E
else:
    # works with python -m pkg.tcp 
    # or when imported by another module 
    from pkg.usefulEnums import UsefulEnums as E
    # This works as well and appears more more portable and pythonic
    # but the logic that makes it work is obtuse and fragile
    # and it doesn't work if __package__ is None (even though it should!) 
    # from .usefulEnums import UsefulEnums as E    

 def profound():
     print('The value of {} is {}'.format(E.ZERO.name, E.ZERO.value))
 if __name__ == '__main__':
     profound()

主项目代码如预期:

cat proj/myProj.py
from pkg.usefulEnums import UsefulEnums as E
import pkg.usefulCode as u
if __name__ == '__main__':
    u.profound()

以上是我接受的解决方法,作为我陈述的问题的答案,但我无法理解推理。

我不明白为什么在未定义 __package__ 时“点”导入的行为无法按预期工作。当然它总是意味着相对于当前包的导入,如果没有明确定义包,那么为什么不意味着从与当前模块相同的目录导入,这可以说是当前的默认包?

【讨论】:

    猜你喜欢
    • 2021-12-17
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 2019-01-05
    • 2021-05-31
    • 2019-06-29
    相关资源
    最近更新 更多