从包中导入父目录中的一个模块

19 浏览
0 Comments

从包中导入父目录中的一个模块

我查阅了几个帖子和文章,包括:

但是我无法得到预期的结果。

假设我有一个名为"helloworld"的目录:

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

这是say_hello.py:

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

这是import_hello.py:

from .. import say_hello
say_hello.hello_world()

我希望在调用python /path/to/import_hello.py时能够导入say_hello模块,而不使用sys模块。

然而,当我执行python /path/to/import_hello.py时,它会返回ValueError: attempted relative import beyond top-level package,我不知道为什么它不起作用。

甚至这样也不行:

from helloworld import say_hello
say_hello.hello_world()

它会给我返回ModuleNotFoundError: No module named 'helloworld'

0
0 Comments

在包中从父目录导入模块的问题可能是由于Python的导入机制导致的。当我们在一个包内部导入模块时,Python只会在当前包的目录下查找模块,而不会自动查找父目录。

要解决这个问题,我们可以尝试将父目录的路径添加到系统路径中,然后进行导入操作。可以使用sys模块的path属性来获取系统路径,并使用os模块的abspath函数获取父目录的绝对路径。

下面是解决该问题的示例代码:

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

以上代码中,我们首先导入sys模块的path属性并将其赋值给变量pylib。然后导入os模块,并使用os.path.abspath函数获取当前目录的父目录的绝对路径,并将其添加到pylib中。最后,我们可以从父目录的模块helloworld中导入函数say_hello。

希望这可以帮助你解决问题!

0
0 Comments

问题的原因是在一个包的中间运行脚本时,无法从父目录导入模块。这是因为在运行脚本时,实际上是从当前脚本所在的目录开始运行,而不是从父目录开始运行。因此,无法使用".."来导入父目录的模块。

解决方法有两种:

1. 使用-m来运行模块:$ python -m helloworld.another_hello.import_hello。需要确保helloworld所在的目录在sys.path中,可以通过将其安装到site-packages中,或者将当前工作目录设置为其父目录,或者设置PYTHONPATH来实现。

2. 更常用的方法是在顶层编写"entry point"脚本。在顶层脚本中导入需要的模块,并调用相应的函数。例如:

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

。如果使用setuptools,可以在安装时自动创建这些入口脚本。具体可以参考setuptools的文档中的Automatic Script Creation部分。

另外,使用from … import导入模块是可行的,但通常建议将顶层代码(如say_hello.hello_world())移到一个函数中,在其他地方导入import_hello后再调用该函数。这样可以避免在每次导入时自动运行顶层代码。换句话说,应该在包中使用模块而不是脚本。

希望这些能够帮助你解决问题。如果你在使用setuptoolsconsole_scripts中遇到了ModuleNotFoundError,可能需要查看setup.py中的其他部分,因为setuptools的文档相对庞大而复杂。

0