Python3导入更改

时间:2018-08-24 15:59:29

标签: python-3.x

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

我在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”错误。 我想在'sub'目录中使用three.py,该目录使用e1.py中定义的枚举,并且可以在本地运行以进行自检等,并且可以从不在同一目录中的外部模块中包含。

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

2 个答案:

答案 0 :(得分:0)

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

__init__

,然后在要使用的文件中添加:

import my.proj.sub.e1

答案 1 :(得分:0)

给出结构:

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

我希望能够在自测模式下运行有用的Code.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 __ 时'dot'导入行为无法按预期方式工作。当然,它总是意味着相对于当前软件包的导入,如果没有显式定义软件包,那为什么不意味着从与当前模块相同的目录中导入,这可能是当前默认软件包?