Brian H.
Brian H.

Reputation: 2225

In Python, is it possible to access the global namespace from within a function

I'm learning Python coming from a good background with other languages. My question is mostly academic, as I know that what I'm asking is seldom needed and is definitely not a good programming practice.

Here is what I'm asking:

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

Attempt #1

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

This results in an error: name 'x' is assigned to before global declaration.

Attempt #2

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

The Python documentation on namespaces states suggest that #2 (or something like it) should be possible. See Python Tutorial 9.2

"The statements executed by the top-level invocation of the interpreter, either read from a script file or interactively, are considered part of a module called __main__, so they have their own global namespace."

However attempting to access __main__ from either a script or the console results in an error. Also, the global attribute __name__ refers to the outermost module as __builtins__, but this only contains the built-in variables, not any user defined global ones. If the variable were delcared in an outside module, one that had been imported, it could be accessed with __module_name__.variable.

Upvotes: 9

Views: 9383

Answers (4)

debug
debug

Reputation: 1079

If python3, you can try the following method.

#!/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")')

Upvotes: -1

MaxU - stand with Ukraine
MaxU - stand with Ukraine

Reputation: 210832

try globals():

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


func()

Upvotes: 8

BrenBarn
BrenBarn

Reputation: 251355

You can use globals()['x']. However, you're better off just giving your local variable a different name so you can just do global x to do whatever you need to do with the global variable.

Upvotes: 6

zondo
zondo

Reputation: 20336

globals() returns a dictionary of the current global variables. You can print globals()['x'].

Upvotes: 5

Related Questions