You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python 3.7中如何从包内util.py导入__init__.py内容?

解决foo包中util.py访问__init__.py内容的问题

这个错误的根源在于你误解了__init__的含义:当你在util.py中执行from . import __init__时,你导入的并不是__init__.py模块本身,而是当前util.py模块对象的内置__init__方法(这是一个method-wrapper对象),它当然没有你在__init__.py里定义的some_var_in_init属性。

下面是几种可行的解决方法,以及更合理的代码重构建议:

方法1:直接相对导入需要的对象

既然__init__.py里的内容就是foo包的公共属性,你可以直接从包本身相对导入需要的变量、类或函数:

# util.py
from . import some_var_in_init
# 或者一次性导入多个对象
from . import some_var_in_init, MyClassFromInit, my_function

print(some_var_in_init)

方法2:导入整个包模块

如果你需要访问__init__.py里的多个内容,也可以直接导入foo包本身,然后通过包对象访问属性:

# util.py
import foo
print(foo.some_var_in_init)

# 或者用相对导入更符合包内代码规范
from . import foo as foo_package
print(foo_package.some_var_in_init)

推荐:代码重构(避免__init__.py臃肿)

随着包的功能扩展,把所有代码都放在__init__.py里会让文件越来越臃肿,不利于维护。推荐的做法是拆分代码到专门的模块中,同时在__init__.py中导出这些内容,保持外部导入的兼容性:

重构后的目录结构

foo/
    __init__.py
    util.py
    core.py  # 存放原来__init__.py中的核心代码

步骤1:迁移代码到core.py

把原来__init__.py里的类、函数、变量移到core.py

# core.py
some_var_in_init = "你的变量值"

class MyCoreClass:
    def __init__(self):
        pass

def my_core_function():
    return "核心函数返回值"

步骤2:在__init__.py中导出内容

这样外部用户执行import foo时,依然能访问到原来的内容,保持兼容性:

# __init__.py
from .core import some_var_in_init, MyCoreClass, my_core_function

步骤3:在util.py中导入core模块的内容

现在可以直接从core模块导入,代码结构更清晰:

# util.py
from .core import some_var_in_init, MyCoreClass

print(some_var_in_init)

这种重构方式不仅解决了当前的导入问题,还让包的结构更合理,便于后续扩展和维护。

内容的提问来源于stack exchange,提问作者Al Sweigart

火山引擎 最新活动