You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将__main__.py作为Python模块入口实现常规导入?

问题描述

文件结构如下:

parent_folder
├── caller.py
└── app
    ├── script_1.py
    ├── script_2.py
    └── __main__.py

__main__.py作为app模块的入口文件,代码如下:

# __main__.py
from app.script_1 import MyClassB
from app.script_2 import MyClassC


class MyClassA:
    def __init__(self):
        print('This instanciate a MyClassA object')

def func_a():
    print('Some Function')

caller.py的代码:

# caller.py
import app
app.func_a()
obj_a = app.MyClassA()

在Windows 10的Python 3.8.10环境下运行python caller.py时,出现报错:

Traceback (most recent call last):
  File "caller.py", line 2, in <module>
    app.func_a()
AttributeError: module 'app' has no attribute 'func_a'

已知修改caller.py为import app.__main__ as app可正常运行,但这种方式不符合常规模块导入习惯,请问如何才能将__main__.py作为模块入口实现常规导入?

解决方案

Python中import app时,实际导入的是app模块的__init__.py文件(若存在),而非__main__.py。__main__.py的作用是当用python -m app直接运行模块时作为入口,或模块被当作脚本执行时使用,但它不会自动成为app模块的公开接口一部分。要实现常规import app就能访问相关内容,有两种常用方法:

方法1:创建__init__.py导入__main__内容

在app文件夹下创建__init__.py文件,内容如下:

# app/__init__.py
from .__main__ import MyClassA, func_a

这样import app时,app模块会自动将__main__.py里的MyClassA和func_a导入自身命名空间,caller.py无需修改即可正常调用。

方法2:分离核心代码与入口逻辑(更规范)

把__main__.py中的核心代码迁移到单独模块,再让__init__.py和__main__.py分别导入:

  1. 在app文件夹下创建core.py:
# app/core.py
from app.script_1 import MyClassB
from app.script_2 import MyClassC


class MyClassA:
    def __init__(self):
        print('This instanciate a MyClassA object')

def func_a():
    print('Some Function')
  1. 修改app/__init__.py:
# app/__init__.py
from .core import MyClassA, func_a
  1. 修改app/__main__.py(保留模块直接运行的入口功能):
# app/__main__.py
from .core import *

# 可添加模块直接运行时的逻辑,比如:
if __name__ == '__main__':
    func_a()
    obj_a = MyClassA()

这种方式符合Python模块设计规范,分离核心代码与入口逻辑,便于后续维护和扩展。

内容的提问来源于stack exchange,提问作者Alexandre de Castro Maciel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 19:16:03