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

如何获取Python模块中自身定义的变量(不含导入内容)

如何获取Python模块中自身定义的变量(排除导入内容)

嘿,这个场景我太熟悉了!当用from base import *把其他模块的变量一股脑导入后,dir()或者inspect.getmembers()确实会把导入的变量也混进来,想要只拿到模块自身定义的变量,有几个靠谱的方法:

方法1:用AST解析模块源码(最准确)

直接从模块的源码文件里提取顶层定义的变量,完全不受导入内容的干扰,是最稳妥的方案。

代码示例:

import ast
import extended

def get_self_defined_vars(module):
    # 获取模块的源码文件路径
    module_path = module.__file__
    with open(module_path, 'r', encoding='utf-8') as f:
        tree = ast.parse(f.read())
    
    self_vars = []
    # 遍历AST树,提取顶层赋值语句的变量名
    for node in ast.walk(tree):
        # 处理普通赋值(比如baz = 3)
        if isinstance(node, ast.Assign):
            for target in node.targets:
                if isinstance(target, ast.Name):
                    self_vars.append(target.id)
        # 处理带注解的变量定义(比如qux: int = 4)
        elif isinstance(node, ast.AnnAssign):
            if isinstance(node.target, ast.Name):
                self_vars.append(node.target.id)
    return self_vars

# 调用函数获取结果
print(get_self_defined_vars(extended))  # 输出 ['baz', 'qux']

这个方法的优势是不管你用什么方式导入外部变量,都能精准定位到模块自身定义的变量,唯一的小限制是需要能读取到模块的源码文件(动态生成的模块不适用,但普通.py文件完全没问题)。

方法2:对比模块属性的差异

如果你明确知道导入的外部模块是哪些,可以通过对比空模块的默认属性、外部模块的属性,来筛选出当前模块自己的变量。

代码示例:

import types
import sys
# 先创建一个空模块,拿到模块默认自带的属性列表
empty_module = types.ModuleType("empty")
default_attrs = set(dir(empty_module))

# 导入目标模块和被导入的外部模块
import extended
import base

# 计算当前模块独有的属性:所有属性 - 默认属性 - 外部模块的属性
self_vars = set(dir(extended)) - default_attrs - set(dir(base))
print(sorted(self_vars))  # 输出 ['baz', 'qux']

这个方法简单直接,但需要你清楚知道所有被导入的外部模块,如果导入了多个模块,得把它们的属性都一起减去才行。

方法3:混合判断成员来源

对于模块里的函数、类这类有__module__属性的对象,可以直接判断归属;对于基本类型变量,就排除掉外部模块里有的名字,混合使用来筛选。

代码示例:

import inspect
import extended
import base

self_members = []
for name, member in inspect.getmembers(extended):
    # 先排除模块自带的双下划线属性(比如__name__、__file__)
    if name.startswith('__') and name.endswith('__'):
        continue
    # 对有__module__属性的对象,判断是否属于当前模块
    if hasattr(member, '__module__'):
        if member.__module__ == extended.__name__:
            self_members.append(name)
    # 对基本类型变量,判断是否不在外部模块的属性列表里
    else:
        if name not in dir(base):
            self_members.append(name)

print(self_members)  # 输出 ['baz', 'qux']

这个方法适合模块里既有自定义对象又有基本变量的场景,但如果外部模块和当前模块有同名变量,可能会误判,所以最好还是优先用AST的方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:26:27