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

Cherrypy技术问询:globals()为何有时缺失模块函数及a_builder页面偶发404?

关于globals()缺失模块函数的问题

首先得明确:globals()返回的是当前执行作用域的全局命名空间字典。当你的模块被另一个模块导入时,Python会执行模块的顶层代码(也就是不在任何函数/类内部的代码),所有顶层定义的函数、变量都会被加入模块的globals字典里。如果出现缺失,大概率是这几个场景:

  • 条件性函数定义:如果你的函数是在if/else这类条件块里定义的,当导入模块时条件不满足,函数就不会被创建,自然不会出现在globals()里。比如:

    # 你的模块代码
    import os
    if os.environ.get("DEBUG") == "True":
        def debug_only_func():
            pass
    

    如果导入时DEBUG环境变量没设为True,debug_only_func就不会出现在globals()里。

  • 模块导入缓存未更新:Python会缓存已导入的模块(存在sys.modules里)。如果你修改了模块代码后,没有重新启动解释器或者强制重新加载模块,导入的还是旧版本的模块,新添加的函数自然不在globals()里。这种情况在开发时很常见,尤其是修改代码后直接重新运行调用脚本,而没重启进程。

  • 错误的作用域调用:如果你是在某个函数内部调用globals(),注意这里的globals()返回的是该函数定义所在模块的全局命名空间,而不是调用该函数的模块的。如果你的函数是在其他模块定义的,那调用它时的globals()就不是你当前模块的。


关于a_builder加载网页返回404的问题

你提到修改a_builder代码后常触发这个问题,结合前面的模块缓存问题,我觉得大概率和缓存或代码变更后的请求不一致有关:

  • 模块缓存导致旧代码仍在运行:修改a_builder代码后,Python可能还在使用缓存的旧模块版本,导致生成的请求URL/参数还是旧的,而旧资源已经被移除,所以返回404。解决方法是在开发时强制重新加载模块,比如用importlib.reload()

    import importlib
    import a_builder
    importlib.reload(a_builder)
    

    不过生产环境不建议这么做,开发时用用没问题。

  • 代码修改导致请求URL错误:修改网页内容时,可能不小心改了请求的URL路径、查询参数或者域名,比如拼写错误、路径少了个斜杠,导致请求的资源不存在。这种情况可以在a_builder里加日志,把每次请求的URL打出来,对比修改前后的URL是否正确。

  • 服务器端缓存或资源更新延迟:如果你请求的是第三方网页,可能对方服务器有缓存,修改代码后你请求的新内容还没被服务器同步,或者对方已经移除了旧资源但你还在请求旧路径。这种情况可以尝试在请求里加随机参数(比如?t=时间戳)来绕过缓存。

  • a_builder内部的缓存机制:如果a_builder自己实现了请求缓存(比如把之前的请求结果存在内存或文件里),修改代码后缓存没清空,导致返回的是旧的404结果。检查下a_builder里有没有缓存相关的逻辑,比如用lru_cache装饰器或者自定义的缓存字典,修改代码后需要清空这些缓存。


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

火山引擎 最新活动