1

parent/__init__.py:

    favorite_numbers = [1]

    def my_favorite_numbers():
        for num in favorite_numbers:
            num

    my_favorite_numbers()

    from .child import *

    my_favorite_numbers()

parent/child.py:

    print favorite_numbers

    favorite_numbers.append(7)

I then created a file one directory up from parent directory named tst.py:

    import parent

So the directory structure looks like this:

    parent (directory)
        __init__.py (file)
        child.py (file)
    tst.py (file)

And I get this error upon execution:

    NameError: name 'favorite_numbers' is not defined

How can I add a value to favorite_numbers within child.py so that when I execute the my_favorite_numbers() function, I get 1 and 7.

1
  • For future reference, to deal with things like __init__.py, you can either embed it as a fragment of code in backticks: `__init__.py` (what I did above), or backslash-escape the underscores: \_\_init.py\_\_ (which gives you __init.py__), whichever seems appropriate. Commented May 10, 2015 at 18:18

2 Answers 2

3

In Python, each module has its own separate globals. That's actually the whole point of modules (as opposed to, say, C preprocessor-style text inserts).

When you do from .child import *, that imports .child, then copies all of its globals into the current module's globals. They're still separate modules, with their own globals.


If you want to pass values between code in different modules, you probably want to wrap that code up in functions, then pass the values as function arguments and return values. For example:

parent/__init__.py:

from .child import *

favorite_numbers = [1]

def my_favorite_numbers():
    for num in favorite_numbers:
        num

my_favorite_numbers()

child_stuff(favorite_numbers)

my_favorite_numbers()

parent/child.py:

def child_stuff(favorite_numbers):
    print favorite_numbers

    favorite_numbers.append(7)

In fact, you almost always want to wrap up any code besides initialization (defining functions and classes, creating constants and other singletons, etc.) in a function anyway. When you import a module (including from … import), that only runs its top-level code the first time. If you import again, the module object already exists in memory (inside sys.modules), so Python will just use that, instead of running the code to build it again.


If you really want to push a value into another module's namespace, you can, but you have to do it explicitly. And this means you have to have the module object available by importing it, not just importing from it:

from . import child
child.favorite_numbers = favorite_numbers

But this is rarely a good idea.

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

Comments

0

Did you ever run setup.py or a way of "building" your library?

I would create a setup.py file and likely run it in develop mode. Python setup.py develop vs install

1 Comment

This is a great idea, and would solve a lot of problems with his design that he hasn't noticed yet… but I don't think it would help to solve the particular problem he's asking about here.

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.