使用__init__从子文件夹的文件中的父目录导入?

时间:2016-08-18 14:48:58

标签: python import directory

如果我有这样的目录

dir_one/
    main.py
    __init__.py
    dir_two/
        sub.py
        __init__.py

我的 init .py文件目前都是空的。在我的sub.py文件中,我尝试从main.py导入一个类: e.g。

#File:sub.py
from main import items

哪个不起作用。我也试过

#File:sub.py
from dir_one.main import items

也没有用。

有没有办法从main.py导入sub.py文件?如果它是空的,我是否需要编辑__init__.py

2 个答案:

答案 0 :(得分:1)

在您的文件sub.py中,您可以执行类似

的操作
import os

wd = os.getcwd()    # save current working directory
os.chdir('path/to/dir_one')    # change to directory containing main.py  
from main import items    # import your stuff
os.chdir(wd)    # change back to directory containing sub.py

在使用您的项目之前

修改:在您的具体情况下,'path/to/dir_one'只是一个目录向上,即'..'

答案 1 :(得分:1)

你有几个选择。

您最好的选择是将软件包与使用软件包的脚本分开。请查看entry_points的setuptools。您将setuptools指向包中的函数,并创建一个脚本来调用它。漂亮...

在玩这个时,我已经设置了以下包结构:

test_dir
   + __init__.py
   + main.py
   + sub1
   --+ __init__.py
   --+ script.py
   + sub2
   --+ __init__.py
   --+ module.py

我确保test_dir可通过PYTHONPATH访问。

脚本都非常简单(只是打印一些东西):

# main.py
def func_in_main():
    print("Hello from main.py!")

# module.py
def run_func():
    print("Hello from script in sub2.py!")

# script.py
from ..sub2 import module
from .. import main

def entry_point():
    module.run_func()
    main.func_in_main()

if __name__ == '__main__':
    entry_point()

现在,如果我尝试直接运行会怎么样?

$ python test_package/test_dir/sub1/script.py 
Traceback (most recent call last):
  File "test_package/test_dir/sub1/script.py", line 2, in <module>
    from ..sub2 import module
ValueError: Attempted relative import in non-package

嗯......糟糕(我试图在原始问题的评论中描述这种情况)。顺便说一句,无论我当前的工作目录如何都会发生这种情况......但是,从我的文件系统的任何地方,我可以使用-m标志 1 来运行它:

$ python -m test_dir.sub1.script 
Hello from script in sub2.py!
Hello from main.py!

Horray!我们只需要指定模块路径,然后我们就会变黄(请记住,test_dir 必须可通过您的PYTHONPATH访问以实现此目的。好的,但如果我们真的想调用脚本而不是使用模块路径呢?如果是这种情况,我们可以在进行任何导入之前修改__package__变量:

# script.py (updated)
if __name__ == '__main__' and __package__ is None:
    __package__ = 'test_dir.sub1'
    import test_dir  # needed to suppress SystemError -- I'm not sure why...

from .. import main
from ..sub2 import module

def entry_point():
    module.run_func()
    main.func_in_main()

if __name__ == '__main__':
    entry_point()

现在让我们尝试再次直接运行这个东西:

$ python test_package/test_dir/sub1/script.py 
test_package/test_dir/sub1/script.py:4: RuntimeWarning: Parent module 'test_dir.sub1' not found while handling absolute import
  import test_dir
Hello from script in sub2.py!
Hello from main.py!

我们仍然得到RuntimeWarning,但它运行正常。有关详细信息,请查看PEP-0366

1 一般来说,我从包外面运行了大部分这些(高于test_dir的一级),但如果我从里面包。使用-m,您总是指定模块的完整路径(test_dir.sub1.script),没有它,您只需指定文件的相对或绝对路径)