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

Python3中exec()无法从外部.py文件导入变量问题排查

Python2.7转3.6:exec执行外部脚本后变量未定义问题

问题说明

将Python2.7脚本迁移至3.6时,原本用于读取外部rules.py文件并导入变量的函数报错,提示notify_rules未定义。

原加载函数代码

def _load_rules(old_hash=''):
    # Determine if the rules file has changed, and if so reload it
    rules = open(rules_file, 'r').read()
    new_hash = md5(b'rules').hexdigest()
    if new_hash != old_hash:
        exec(rules)
        # C{ignore_rules} and C{notify_rules} come from the script execution
        return (new_hash, ignore_rules, notify_rules)
    return (old_hash, None, None)

外部rules.py代码

import datetime
import re

notify_rules = \
        [{'event': 'failure',
          'access_point': None,
          'expression': re.compile(r'some_regex'),
          'addresses': ['some_email@email.com']},
     {'event': 'failure',
          'access_point': 'access_point_',
          'addresses': ['some_email@email.com']},

ignore_rules = \
        [{'access_point': 'something'},
         {'access_point': 'something'},
         {'access_point': 'something'},
         {'access_point': 'something'},]

报错信息

File "/app/eam/gaic/ai_mon/monitoring.py", line 174, in _load_rules
            return (new_hash, notify_rules, ignore_rules)
        builtins.NameError: name 'notify_rules' is not defined

问题原因及解决方案

1. 修复rules.py的语法错误

原rules.py中notify_rules的列表未闭合(缺少]),导致exec执行脚本时直接失败,变量根本没被定义。修正后的rules.py:

import datetime
import re

notify_rules = \
        [{'event': 'failure',
          'access_point': None,
          'expression': re.compile(r'some_regex'),
          'addresses': ['some_email@email.com']},
         {'event': 'failure',
          'access_point': 'access_point_',
          'addresses': ['some_email@email.com']}]  # 补充闭合的]

ignore_rules = \
        [{'access_point': 'something'},
         {'access_point': 'something'},
         {'access_point': 'something'},
         {'access_point': 'something'},]

2. 适配Python3中exec的作用域规则

Python3里exec默认不会将执行产生的变量注入当前函数作用域,需要显式传递命名空间字典来保存变量。同时原代码的哈希计算逻辑错误(固定对b'rules'取哈希,无法检测文件变更),一并修正:

修改后的_load_rules函数:

import hashlib  # 需要导入hashlib

def _load_rules(old_hash=''):
    # 检测规则文件是否变更,变更则重新加载
    with open(rules_file, 'r', encoding='utf-8') as f:
        rules = f.read()
    
    # 对文件内容计算哈希,正确检测文件变更
    new_hash = hashlib.md5(rules.encode('utf-8')).hexdigest()
    
    if new_hash != old_hash:
        # 创建命名空间字典,用于保存exec执行后的变量
        local_vars = {}
        exec(rules, globals(), local_vars)
        # 从命名空间字典中取出需要的变量
        return (new_hash, local_vars['notify_rules'], local_vars['ignore_rules'])
    return (old_hash, None, None)

关键说明

  • 使用with语句打开文件,更安全且自动关闭文件句柄
  • 修正哈希计算逻辑:基于读取的文件内容生成哈希,确保能正确检测文件变更
  • 通过exec(rules, globals(), local_vars)将执行结果存入local_vars,再从字典中提取变量,适配Python3的作用域规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 10:34:53