1

i've run through many posts about this, but still doesn't seem to work. The deal is pretty cut. I've the got the following hierarchy.

main.py
DirA/
    __init__.py
    hello.py
DirB/
    __init__.py
    foo.py
    bla.py
    lol.py

The__init__.py at DirA is empty. The respective one at DirB just contains the foo module.

__all__.py = ["foo"]

The main.py has the following code

import DirA
import DirB

hey()        #Def written at hello.py
foolish1()   #Def written at foo.py
foolish2()   #Def written at foo.py

Long story short, I got NameError: name 'foo' is not defined. Any ideas? Thanks in advance.

Billy Grande
  • 577
  • 3
  • 11
  • 23

3 Answers3

3

You only get what you import. Therefore, in you main, you only get DirA and DirB. You would use them in one of those ways:

import DirA
DirA.something_in_init_py()

# Importing hello:
import DirA.hello
DirA.hello.something_in_hello_py()

# Using a named import:
from DirA.hello import something_in_hello_py
something_in_hello_py()

And in DirB, just make the __init__.py empty as well. The only use of __all__ is for when you want to import *, which you don't want because, as they say, explicit is better than implicit.

But in case you are curious, it would work this way:

from DirB import *
something_in_dirb()

By default the import * will import everything it can find that does not start with an underscore. Specifying a __all__ restricts what it imported to the names defined in __all__. See this question for more details.

Edit: about init.

The __init__.py is not really connected to the importing stuff. It is just a special file with the following properties:

  • Its existence means the directory is a python package, with several modules in it. If it does not exist, python will refuse to import anything from the directory.
  • It will always be loaded before loading anything else in the directory.
  • Its content will be available as the package itself.

Just try it put this in DirA/__init__.py:

foo = 42

Now, in your main:

from DirA import foo
print(foo)  # 42

It can be useful, because you can import some of your submodules in the __init__.py to hide the inner structure of your package. Suppose you build an application with classes Author, Book and Review. To make it easier to read, you give each class its own file in a package. Now in your main, you have to import the full path:

from myapp.author import Author
from myapp.book import Book
from myapp.review import Review

Clearly not optimal. Now suppose you put those exact lines above in your __init__.py, you may simplify you main like this:

from myapp import Author, Book, Review

Python will load the __init__.py, which will in turn load all submodules and import the classes, making them available on the package. Now your main does not need to know where the classes are actually implemented.

Community
  • 1
  • 1
spectras
  • 13,105
  • 2
  • 31
  • 53
  • The 3rd option seems to be more my style :P Works fine, just a couple of questions. Why not import * and explicitly name each definition? And, what happens with __init__.py when you want to import *? Thanks – Billy Grande Oct 08 '15 at 16:19
  • Added some hints about the use of `__init__.py`, please tell me if it helps. – spectras Oct 08 '15 at 16:36
  • Billy Grande: Using `import *` is the coding equivalent of picking your nose. It doesn't bother you when you do it in private, but you find it disgusting when someone else does it. – JS. Oct 08 '15 at 16:41
  • @spectras - the "Edit: about init" is what really makes this reply useful. Thank you. – skitheo Feb 03 '22 at 23:53
1

Have you tried something like this: One way

from DirA import hello

Another way

from DirA.hello import hey 

If those don't work then append a new system path

reticentroot
  • 3,612
  • 2
  • 22
  • 39
0

You need to import the function itself:

How to call a function from another file in Python?

In your case:

 from DirA import foolish1, foolish2
Community
  • 1
  • 1
Antony
  • 1,253
  • 11
  • 19