在Python中,是否可以从函数内访问全局命名空间

时间:2016-02-02 20:52:57

标签: python python-3.x

我正在学习Python与其他语言的良好背景。我的问题主要是学术问题,因为我知道我所要求的内容很少需要,绝对不是一个好的编程实践。

以下是我的要求:

x = 'global scope'      # global
def func():
    x = 'local scope'   # global x is now shadowed
    print(global x)     # is this somehow possible?

尝试#1

def attempt1():
    x = 'local scope'   # shadowded
    global x
    print(x)            # error

这会导致错误:在全局声明之前将名称“x”分配给。

尝试#2

def attempt2():
    x = 'local scope'   # shadowded
    print(__main__.x)   # error: __main__ not defined

关于命名空间状态的Python文档表明#2(或类似的东西)应该是可能的。见Python Tutorial 9.2

  

“解释器的顶层调用执行的语句,无论是从脚本文件中读取还是以交互方式读取,都被视为名为__main__的模块的一部分,因此它们具有自己的全局命名空间。”

但是,尝试从脚本或控制台访问__main__会导致错误。此外,全局属性__name__将最外层模块称为__builtins__,但这仅包含内置变量,而不包含任何用户定义的全局变量。如果变量是在外部模块中进行的,那么已导入的模块可以使用__module_name__.variable进行访问。

4 个答案:

答案 0 :(得分:7)

尝试globals():

x = 'global scope'      # global
def func():
    x = 'local scope'   # global x is now shadowed
    print(globals()['x'])     # is this somehow possible?


func()

答案 1 :(得分:5)

您可以使用globals()['x']。但是,你最好只给你的局部变量一个不同的名字,这样你就可以global x做你需要做的全局变量。

答案 2 :(得分:4)

globals()返回当前全局变量的字典。您可以打印globals()['x']

答案 3 :(得分:-1)

如果是python3,则可以尝试以下方法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def list_available_subclasses_names(obj):
    """Check the type if has __globals__ attributes.
    """
    return [
        subobj.__name__
        for subobj in obj.__class__.__base__.__subclasses__()
        # 'wrapper_descriptor' object has no attribute '__globals__'

        if hasattr(subobj.__init__, '__globals__')
    ]


def get_builtin_function(obj, subclass_name, func_name):
    """Get function obj.
    """
    func = None
    for subobj in obj.__class__.__base__.__subclasses__():
        if subclass_name == subobj.__name__:
            __globals__ = subobj.__init__.__globals__       # gloabls is here.
            __builtins__ = __globals__.get('__builtins__')
            func = __builtins__.get(func_name)
            break

    return func


if __name__ == '__main__':
    obj = ''
    subclass_name = 'Repr'  # print(list_available_subclasses_names())

    func_eval = get_builtin_function(obj, subclass_name, 'eval')
    if func_eval:
        func_eval('__import__("os").system("pwd")')