为了账号安全,请及时绑定邮箱和手机立即绑定

导入错误:在没有已知父包的情况下尝试相对导入

导入错误:在没有已知父包的情况下尝试相对导入

噜噜哒 2022-08-25 14:04:35
我正在学习使用python编程,并且我在从包中的模块导入时遇到问题。我正在使用Python 3.8.2 64位的visual studio代码。.vscode├── ecommerce│   ├── __init__.py│   ├── database.py│   ├── products.py│   └── payments│       ├── __init__.py│       ├── authorizenet.py│       └── paypal.py├── __init__.py└── main.py在我拥有的文件中:ecommerce/products.py#products.pyfrom .database import Databasep = Database(3,2)这样我就可以从文件中导入类。但是我收到错误Databaseecommerce/database.pyImportError : Attempted relative import with no known parent package
查看完整描述

4 回答

?
慕的地8271018

TA贡献1796条经验 获得超4个赞

由于您使用的是Python 3.8版本,因此导入的工作方式略有不同,但我认为这应该有效:


使用以下任一方法:


from database import Database

#Database is the class

或尝试:


import database.Database

最后,这个是非常安全的,可能是最佳实践:


from . import Database  

# The '.' (dot) means from within the same directory as this __init__.py module grab the Database class.


查看完整回答
反对 回复 2022-08-25
?
aluckdog

TA贡献1847条经验 获得超7个赞

Python文档和实验来看,似乎相对导入(涉及.,..等)仅在以下情况下有效:

  1. 导入模块具有 除 以外的 一个,并且进一步说,__name____main__

  2. 导入模块pkg.module_name,即它必须从目录层次结构的上方导入(要有一个父 pkg 作为其一部分)。__name____name__

导入模块是通过包含父 pkg 的模块语法指定的,在这种情况下,它仍然是 ,因此它作为脚本运行,但相对导入将起作用。这里设置并用于查找父包,而 是 ;更多 这里.python -m pkg.module__name____main____package____name____main__

[毕竟,这似乎是确定相对进口是否/如何运作的关键。 表示脚本或模块(即或 )。 指示相对导入相对于包中出现的位置,并且顶部需要在 .] 中。__package__sys.path__name____main__module_name__package____package__sys.path

因此,继续@AmitTendulkar的示例,如果您将其作为或从项目根目录运行,或者从该根目录和输入交互式python,或者 products.py 中的相对导入将起作用。> python main.py> python -m main> python -m ecommerce.productsimport mainimport ecommerce.products

但是,如果您或从电子商务目录中,或者从该电子商务目录中输入交互式python,它们将失败。> python products.py> python -m productsimport products

添加是有帮助的

print("In module products __package__, __name__ ==", __package__, __name__)

等在每个文件中进行调试。

更新:

导入的工作方式取决于 和 ,而不是 。发出自 ,有一个 、 的 、 - 工作模块的绝对导入,相对导入失败。sys.path__package____name__/home/jj> python sub/mod.pysys.path__package__/home/jj/subNonesys.path

> python -m sub.mod有 , 的 , - 工作中模块的绝对导入, 相对于 + 的导入工作。sys.path__package__/home/jjsubsys.pathsys.path__package__

添加更有帮助

import sys    
print("In module products sys.path[0], __package__ ==", sys.path[0], __package__)

等在每个文件中进行调试。


查看完整回答
反对 回复 2022-08-25
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

我在Windows上遇到了类似的问题,对我有帮助的是(适应你的目录):


# local imports

import sys

sys.path.append(r"C:\path\to\your\project")


from ecommerce.database import Database


查看完整回答
反对 回复 2022-08-25
?
长风秋雁

TA贡献1757条经验 获得超7个赞

考虑以下基本文件结构


├── ecommerce

│   ├── __init__.py

│   ├── database.py

|   └── products.py

└── main.py

我假设您正在从项目根目录运行。python main.py


以下是从Python教程复制的文本,解释了有关相对导入的基本规则,


请注意,相对导入基于当前模块的名称。因为主模块的名称总是,所以用作Python应用程序的主模块的模块必须总是使用绝对导入。__main__


所以下面的代码会起作用,


# main.py

import ecommerce.products 

# or to use it directly 

# from ecommerce.products import my_product


ecommerce.products.my_product()

您的 product.py 可能看起来像这样:


# ecommerce/products.py

from .database import Database


def my_product():

    p = Database(3, 2)

database.py 将如下所示,


# ecommerce/database.py


class Database():

    def __init__(self, x, y):

        self._x = x

        self._y = y

        print('Inside DB init')


    # Rest of the methods...

你现在会得到,


> python main.py

Inside DB init

理想情况下,根目录的文件不是必需的,因为包名称是从电子商务开始的。__init__.py


您也可以运行命令直接调用 products.py。但这不会产生任何输出,因为我们没有调用my_product()函数(仅定义它)。python -m ecommerce.products


调用将不起作用,因为当前模块的名称将变为 而不是 。相对导入仅在当前包中使用时才有效(因此在主脚本中,您始终需要导入包)。python ecommerce/products.py__main__ecommerceecommerce


查看完整回答
反对 回复 2022-08-25
  • 4 回答
  • 0 关注
  • 112 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信