0

First I will say that this is an assignment and the behavior required is not under my control. I am creating a script called globaltest.py that should act exactly the same if the file is run or if the function within the file is called. I am doing both from ipython. It should create a dictionary called station_dict that can be accessed in the ipython console or seen with the whos command.

from globaltest import file_to_dict
file_to_dict()

This should make a variable called station_dict when the function is run.

And here is the behavior when the script is simply being run:

Run globaltest

This should also create a dictionary called station_dict.

The issue is calling and using the function file_to_dict does not create the variable while just running the file does. Here is my code. Thanks for any help.

#!//bin/env python3

def main():

    global station_dict

    station_dict = {}

    station_dict['foo'] = 'bar'

def file_to_dict():

    global station_dict

    station_dict = {}

    station_dict['foo'] = 'bar'

if __name__ == '__main__':
    main()

Here is the bad output as a result of using the function:

Python 3.4.5 |Continuum Analytics, Inc.| (default, Jul  2 2016, 17:47:47)
Type "copyright", "credits" or "license" for more information.

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from globaltest import file_to_dict

In [2]: file_to_dict()

In [3]: whos
Variable       Type        Data/Info
------------------------------------
file_to_dict   function    <function file_to_dict at 0x7f869f39cea0>

Here is the good output as a result of running the program:

Python 3.4.5 |Continuum Analytics, Inc.| (default, Jul  2 2016, 17:47:47)
Type "copyright", "credits" or "license" for more information.

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: run globaltest.py

In [2]: whos
Variable       Type        Data/Info
------------------------------------
file_to_dict   function    <function file_to_dict at 0x7fb92b7df8c8>
main           function    <function main at 0x7fb92b7df0d0>
station_dict   dict        n=1
12
  • The function file_to_dict does modify/create the global variable, station_dict. You need to provide some sort of minimal reproducible example that shows that it doesn't. Commented Oct 14, 2020 at 21:54
  • I have no idea what you mean when you try to describe your "behavior" like Run a9_[USERNAME]. You need to be precise about what you are doing. Commented Oct 14, 2020 at 21:55
  • You do not have any dictionary by the name station_dict in the global scope to begin with! Commented Oct 14, 2020 at 22:05
  • By the way, why do u import per function. Importing is supposedly outside, it will be faster. Commented Oct 14, 2020 at 22:50
  • 1
    Note, run is not even really running something as a module, I'm pretty sure it just extracts the source-code and exec's it in the main namespace. These sorts of things exist for doing the sorts of shenanigans and prototyping you need to do in a shell environment, but they aren't meant to be used in production environments. Commented Oct 15, 2020 at 0:33

1 Answer 1

2

There are two things going on here:

  1. What Python calls "global" is not really global, it's module-level (i.e. in the module namespace). So when you run file_to_dict, station_dict becomes set in globaltest's namespace, though that namespace is not bound (i.e. not imported), so station_dict is inaccessible. To access it, you could do:

    import globaltest
    globaltest.station_dict
    
  2. IPython's %run runs the code in the interpreter's namespace.

That said, I don't know how to achieve what you want. As far as I know, a function can't set variables in its calling namespace, although it might be possible by getting into hacky stuff like inspect.

If it helps, you could read about sharing variables between modules.

Sign up to request clarification or add additional context in comments.

1 Comment

You can get "global globals" by using the __builtins__ namespace, although, that is super hacky. In CPython, modying the namespace of the caller, in general, is not really feasible. You could probably get to the caller using inspect, but then, there's no easy way to modify local namespaces without some serious hackery, I've never seen it done but I won't say it's impossible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.