简体   繁体   English

从包内的父目录导入模块

[英]Import a module from the parent directory within packages

I've referred to several threads and articles including:我已经提到了几个主题和文章,包括:

but can't get the desired result.却得不到想要的结果。

Say I have a directory called "helloworld":假设我有一个名为“helloworld”的目录:

helloworld
|--__init__.py
|--say_hello.py
|--another_hello
   |--__init__.py
   |--import_hello.py

This is say_hello.py:这是 say_hello.py:

def hello_world():
    print("Hello World!")
if __name__ == "__main__":
    hello_world()

This is import_hello.py:这是 import_hello.py:

from .. import say_hello
say_hello.hello_world()

I am hoping to import say_hello module wherever I call python /path/to/import_hello.py without using sys module .我希望在我调用python /path/to/import_hello.py任何地方导入say_hello模块而不使用sys module

However, now when I do python /path/to/import_hello.py , it will return ValueError: attempted relative import beyond top-level package , and I have no idea why it isn't working.但是,现在当我执行python /path/to/import_hello.py ,它将返回ValueError: attempted relative import beyond top-level package ,我不知道为什么它不起作用。

Even this doesn't work:即使这不起作用:

from helloworld import say_hello
say_hello.hello_world()

It will give me ModuleNotFoundError: No module named 'helloworld' .它会给我ModuleNotFoundError: No module named 'helloworld'

You can't run a script out of the middle of a package like that.你不能在这样的包中间运行脚本。 When you do that, you're not running helloworld.another_hello.import_hello based out of /path/to/helloworldsparent/ , you're running __main__ based out of /path/to/helloworldsparent/helloworld/another_hello .当你这样做,你没有运行helloworld.another_hello.import_hello基于出/path/to/helloworldsparent/ ,你正在运行__main__基于出/path/to/helloworldsparent/helloworld/another_hello So, it doesn't have a parent package to import as .. .因此,它没有要import..的父包。


You can run the module with -m :您可以使用-m运行模块:

$ python -m helloworld.another_hello.import_hello

… assuming helloworld 's directory is on your sys.path (eg, because you've installed it into site-packages , or because your current working directory is its parent, or because you've set up a PYTHONPATH ). ...假设helloworld的目录在您的sys.path (例如,因为您已将其安装到site-packages ,或者因为您当前的工作目录是其父目录,或者因为您已经设置了PYTHONPATH )。


But a cleaner solution is usually to leave the deep modules alone and write "entry point" scripts at the top level that look like this:但更简洁的解决方案通常是不理会深层模块,并在顶层编写“入口点”脚本,如下所示:

import helloworld.another_hello.import_hello
helloworld.another_hello.import_hello.main()

If you're using setuptools (and you really should be for anything complicated enough to need two levels of packages), you can make it create the entry point scripts automatically at install time (or at --inplace time, during development).如果您正在使用setuptools (并且您确实应该使用足够复杂的任何东西以需要两个级别的包),您可以让它在安装时(或在--inplace时,在开发期间)自动创建入口点脚本。 See Automatic Script Creation in the docs (but you're probably going to need to read other sections as well to get the whole idea; the docs are pretty large and complicated).请参阅文档中的自动脚本创建(但您可能还需要阅读其他部分以了解整个想法;文档非常大且复杂)。

I feel you can first try to add the parent path to the system path and then try using the import.我觉得你可以先尝试将父路径添加到系统路径中,然后尝试使用导入。

from sys import path as pylib
import os
pylib += os.path.abspath('..')
from helloworld import say_hello

Hope it helps !!希望能帮助到你 !!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM