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

Python开发RPG时调用rpgLocations.Tavern报部分初始化模块无属性错误

问题成因

该报错是循环导入导致的模块初始化不完全:

  • 你在main.py中导入了rpgLocations模块,同时rpgLocations.py顶部又导入了main模块,两个模块形成双向依赖
  • Python导入模块时会先在缓存sys.modules中查找对应模块,找不到就会先创建一个空的模块对象加入缓存,再执行模块内的代码完成初始化
  • 首次运行时导入顺序刚好走完全量初始化,但后续运行时(尤其是未完全关闭进程、使用热重载/在交互式环境重复运行代码的场景下),main导入rpgLocations时,rpgLocations刚创建空模块对象就反过来导入main,main此时直接调用缓存里还没初始化完的rpgLocations对象的Tavern()方法,自然找不到对应属性,就会触发该报错。
排查步骤
  • 先注释掉rpgLocations.py里的import main代码,直接运行项目,如果报错消失即可确定是循环导入导致的问题
  • 完全关闭运行进程,删除项目下的__pycache__文件夹后重新运行,排除旧缓存干扰
解决方案

按改造成本从低到高有3种可行方案:

方案1:延迟导入main

不需要改动整体结构,把rpgLocations.py里的import main从顶层移到Tavern函数内部即可,只有调用方法时才会导入,避免顶层导入形成循环:

# rpgLocations.py 删掉顶部的import main
def Tavern():
    import main # 改为函数内部延迟导入
    main.clear()
    main.PlayerStatus.CurrentPlayerLocation = 'Tavern'
    print('What would you like to do?\n\n\n')
    while True:
        main.pInput = input('1. Trade\n2. View quests\n3. gamble\n4. Look around\n5. Idk,\n6. Leave\n\n>')
        if main.pInput == '1':
            print('test works')
            break
        elif main.pInput == '6':
            NavigationPanel()

方案2:调整导入顺序

在main.py中,先定义完所有rpgLocations要调用的对象(clear函数、PlayerStatus类、NavigationPanel函数等),再导入rpgLocations:

# main.py 先完成所有公共内容的定义
def clear():
    # 原清屏逻辑
    pass
class PlayerStatus:
    CurrentPlayerLocation = ''
def NavigationPanel():
    # 原导航逻辑
    pass
pInput = ''

# 所有公共内容定义完成后再导入rpgLocations
import rpgLocations

# 后续再调用rpgLocations.Tavern()

方案3:抽离公共模块彻底打破循环依赖

长期更推荐该方案,把两个模块共同依赖的公共对象抽离到单独的common.py中,两个模块都导入common调用对应内容,从根源上解决双向依赖问题:

# common.py 示例,存放所有公共变量、方法
def clear():
    # 原main里的清屏逻辑
    pass
class PlayerStatus:
    CurrentPlayerLocation = ''
pInput = ''
def NavigationPanel():
    # 原导航逻辑
    pass

修改rpgLocations.py导入common即可:

import common
def Tavern():
    common.clear()
    common.PlayerStatus.CurrentPlayerLocation = 'Tavern'
    print('What would you like to do?\n\n\n')
    while True:
        common.pInput = input('1. Trade\n2. View quests\n3. gamble\n4. Look around\n5. Idk,\n6. Leave\n\n>')
        if common.pInput == '1':
            print('test works')
            break
        elif common.pInput == '6':
            common.NavigationPanel()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:06:08