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

Python setuptools:导入时执行函数但脚本运行时不执行?

我来帮你搞定这个问题,分单文件和包结构两种场景详细说明解决方案:

单文件 pysome.py 的实现方案

你之前踩的坑是:通过console_scripts调用时,模块的__name__是pysome而非__main__,导致if __name__ != '__main__'的判断会误触发some_fun()。我们可以通过检查sys.argv[0]的名称来区分「用户主动导入」和「控制台命令运行」两种场景:

# pysome.py
import sys
import os

def some_fun():
    print("执行了 some_fun(模块导入场景)")

def main():
    print("执行了 main(控制台运行场景)")

# 核心判断:仅当模块被主动导入(不是直接运行脚本,也不是控制台命令调用)时执行 some_fun
if __name__ != '__main__' and not sys.argv[0].endswith(('pysome', 'pysome.exe')):
    some_fun()

对应的setup.py配置保持不变:

# setup.py
from setuptools import setup

setup(
    name="pysome",
    version="0.1",
    py_modules=["pysome"],
    entry_points={
        'console_scripts': [
            'pysome=pysome:main'
        ]
    }
)

原理说明

  • 当用户执行import pysome时,sys.argv[0]是用户脚本的名称(比如test.py),不满足后缀判断,条件成立,执行some_fun()。
  • 当用户在控制台运行pysome时,sys.argv[0]是console_scripts生成的脚本名称(Windows下是pysome.exe,Linux/macOS下是pysome),条件不成立,不会执行some_fun()。
  • 当用户直接运行python pysome.py时,__name__是__main__,条件也不成立,符合预期。

包结构的实现方案

你的包结构中,__init__.py的代码会在任何导入包内模块的场景下执行(包括__main__.py导入子模块时)。我们可以用环境变量标记来区分控制台运行和正常导入:

1. 调整包内文件内容

  • pysome/__init__.py:添加环境变量判断,仅在非控制台模式下执行some_fun()
# pysome/__init__.py
import os
from .pysome import *

# 仅当没有控制台标记时,执行 some_fun
if not os.environ.get('PYSOME_CONSOLE'):
    some_fun()
  • pysome/__main__.py:先设置控制台标记,再导入子模块
# pysome/__main__.py
import os
# 设置环境变量,标记当前是控制台运行模式
os.environ['PYSOME_CONSOLE'] = '1'
from .pysome import main

# 控制台入口函数
def main():
    print("执行了 main(控制台运行场景)")
  • pysome/pysome.py:保持你的业务逻辑
# pysome/pysome.py
def some_fun():
    print("执行了 some_fun(模块导入场景)")

2. 调整 setup.py 配置

确保entry_points指向__main__.py的main函数:

# setup.py
from setuptools import setup, find_packages

setup(
    name="pysome",
    version="0.1",
    packages=find_packages(),
    entry_points={
        'console_scripts': [
            'pysome=pysome.__main__:main'
        ]
    }
)

原理说明

  • 当用户执行import pysome时,没有设置PYSOME_CONSOLE环境变量,__init__.py里的条件成立,执行some_fun()。
  • 当用户在控制台运行pysome时,__main__.py先设置环境变量,再导入子模块,此时__init__.py执行时会检测到环境变量,跳过some_fun()的执行。

内容的提问来源于stack exchange,提问作者Roland Puntaier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:22:38