我想从同一目录中的另一个文件导入一个函数。

通常,以下工作之一:

from .mymodule import myfunction
from mymodule import myfunction

…但另一个给了我一个错误:

ImportError: attempted relative import with no known parent package
ModuleNotFoundError: No module named 'mymodule'
SystemError: Parent module '' not loaded, cannot perform relative import

这是为什么?


当前回答

这是我的项目结构

├── folder
|   | 
│   ├── moduleA.py
|   |   |
|   |   └--function1()
|   |       └~~ uses function2()
|   | 
│   └── moduleB.py
|       | 
|       └--function2()
|   
└── main.py
     └~~ uses function1()

这里我的模块A导入模块B,主导入模块A

我在模块A中添加了下面的代码段以导入模块B

try:
    from .moduleB import function2 
except:
    from moduleB import function2 

现在我可以单独执行main.py和moduleA.py

这是解决方案吗?

其他回答

TL;DR:给@Aya的答案,用pathlib库更新,并为未定义__file__的Jupyter笔记本工作:

要导入在..下定义的my_function/my_Folder_where_the_package_lives/my_package.py关于您编写代码的位置。

然后执行以下操作:

import os
import sys
import pathlib

PACKAGE_PARENT = pathlib.Path(__file__).parent
#PACKAGE_PARENT = pathlib.Path.cwd().parent # if on jupyter notebook
SCRIPT_DIR = PACKAGE_PARENT / "my_Folder_where_the_package_lives"
sys.path.append(str(SCRIPT_DIR))

from my_package import my_function

我的样板,以使包中的模块具有可独立运行的相对导入。

包/模块.py

## Standalone boilerplate before relative imports
if __package__ is None:                  
    DIR = Path(__file__).resolve().parent
    sys.path.insert(0, str(DIR.parent))
    __package__ = DIR.name

from . import variable_in__init__py
from . import other_module_in_package
...

现在,您可以以任何方式使用模块:

照常运行模块:python-m package.module将其用作模块:python-c“来自包导入模块”独立运行:python package/module.py或者使用shebang(#!/bin/env-python):package/module.py

NB!如果模块与包同名,则使用sys.path.append而不是sys.path.insert将导致难以跟踪的错误。例如my_script/my_script.py

当然,如果您的包层次结构中有较高级别的相对导入,那么这是不够的,但在大多数情况下,这是可以的。

我正在获取此ImportError:尝试在没有已知父包的情况下进行相对导入

在我的程序中,我使用当前路径中的文件导入其函数。

from .filename import function

然后我用包名修改了当前路径(Dot)。这解决了我的问题。

from package_name.filename import function

我希望上面的答案对你有所帮助。

如果以下导入:

from . import something 

不适用于您,这是因为这是python打包导入,不会与您的常规实现一起使用,下面是一个示例来演示如何使用它:

文件夹结构:

.
└── funniest
    ├── funniest
    │   ├── __init__.py
    │   └── text.py
    ├── main.py
    └── setup.py 

内部__init__.py添加:

def available_module(): 
    return "hello world"

text.py添加:

from . import available_module

在setup.py中添加

from setuptools import setup

setup(name='funniest',
  version='0.1',
  description='The funniest joke in the world',
  url='http://github.com/storborg/funniest',
  author='Flying Circus',
  author_email='flyingcircus@example.com',
  license='MIT',
  packages=['funniest'],
  zip_safe=False)

现在,这是安装软件包最重要的部分:

pip install .

在我们的系统中使用相同Python的任何地方,我们现在都可以这样做:

>> import funnies.text as fun
>> fun.available_module() 

这应该输出“hello world”

您可以在main.py中测试它(这不需要安装任何软件包)

这也是main.py

import funniest.text as fun 
print(fun.available_module())

这是我的项目结构

├── folder
|   | 
│   ├── moduleA.py
|   |   |
|   |   └--function1()
|   |       └~~ uses function2()
|   | 
│   └── moduleB.py
|       | 
|       └--function2()
|   
└── main.py
     └~~ uses function1()

这里我的模块A导入模块B,主导入模块A

我在模块A中添加了下面的代码段以导入模块B

try:
    from .moduleB import function2 
except:
    from moduleB import function2 

现在我可以单独执行main.py和moduleA.py

这是解决方案吗?