代码之家  ›  专栏  ›  技术社区  ›  user541686

如何检查具有给定名称的变量是否为非局部变量?

  •  2
  • user541686  · 技术社区  · 7 年前

    给定一个堆栈帧和一个变量名,如何判断该变量是否是非局部变量?例子:

    import inspect
    
    def is_nonlocal(frame, varname):
        # How do I implement this?
        return varname not in frame.f_locals  # This does NOT work
    
    def f():
        x = 1
        def g():
            nonlocal x
            x += 1
            assert is_nonlocal(inspect.currentframe(), 'x')
        g()
        assert not is_nonlocal(inspect.currentframe(), 'x')
    
    f()
    
    1 回复  |  直到 7 年前
        1
  •  5
  •   user2357112    7 年前

    检查帧的代码对象 co_freevars ,它是代码对象使用的闭包变量名称的元组:

    def is_nonlocal(frame, varname):
        return varname in frame.f_code.co_freevars
    

    请注意,这是一个闭包变量,它是 nonlocal 语句查找。如果要包含所有非本地变量,则应检查 co_varnames (内部范围中未使用局部变量)和 co_cellvars (内部作用域中使用的局部变量):

    def isnt_local(frame, varname):
        return varname not in (frame.f_code.co_varnames + frame.f_code.co_cellvars)
    

    另外,不要把事情搞混了 co_names ,这是目前的错误记录。这个 inspect 博士说 科名 用于局部变量,但 科名 是一种“其他一切”的垃圾箱。它包括全局名称、属性名称和导入中涉及的几种名称——大多数情况下,如果预期执行实际上需要名称的字符串形式,则它将进入 科名 .

    推荐文章