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.

abarnert
  • 354,177
  • 51
  • 601
  • 671
Charles Sounder
  • 591
  • 2
  • 5
  • 16
  • 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. – abarnert May 10 '15 at 18:18

2 Answers2

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.

abarnert
  • 354,177
  • 51
  • 601
  • 671
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

Community
  • 1
  • 1
sahutchi
  • 2,223
  • 2
  • 19
  • 20
  • 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. – abarnert May 10 '15 at 18:20