Import Python submodules using __init__.py

I am learning Python and I cannot understand how import operations in __init__.py .

I understand from the Python tutorial that the __init__.py file initializes the package and that I can import subpackages here.

I am doing something wrong. Could you explain to me (and future Python students) what I am doing wrong?

Here is a simplified example of what I'm trying to do.

This is my file structure:

 package __init__.py test.py subpackage __init__.py hello_world.py 

Content hello_world.py :

 def do_something(): print "Hello, world!" 

subpackage/__init__.py empty.

package/__init__.py contains:

 import test.submodule.do_something 

And finally, test.py contains:

 do_something() 

This is how I try to run hello_world.py using the OSX terminal and Python 3:

 python test.py 

Python then throws the following error:

 NameError: name 'do_something' is not defined 
+7
python
source share
3 answers

You probably already understand that when importing a module, the interpreter creates a new namespace and executes the code of this module with the new namespace, both local and global namespace. When the code completes execution, the module name (or the name specified in any as clause) is bound to the module object just created in the import namespace.

__init__.py in the package performs the same function. A package that has a structure is written as a directory, which can also contain modules (regular .py files) and subdirectories (which must also contain the __init__.py file) for any sub_packages. When a package is imported, a new namespace is created and the __init__.py package is executed with this namespace as a local and global namespace. Therefore, in order to answer your problem, we can disable your file by omitting the top-level package, which will never be considered by the interpreter when test.py starts as a program. Then it will look like this:

 test.py subpackage/ __init__.py hello_world.py 

Now subpackage no longer a subpackage since we removed the containing package as non-essential. Focusing on why the name do_something undefined might help. test.py does not contain an import, and so it is not clear how you expect do_something get a value. You can get it to work using empty subpackage/__init__.py and then test.py can read

 from subpackage.hello_world import do_something do_something() 

Alternatively, you can use subpackage/__init__.py , which reads

 from hello_world import do_something 

which sets the do_something function inside the subpackage namespace when importing a package. Then use test.py , which imports the function from the package, for example:

 from subpackage import do_something do_something() 

The ultimate alternative with the same __init__.py is to use test.py , which simply imports the (sub) package and then uses the relative name to access the required function:

 import subpackage subpackage.do_something() 

to access it in your local namespace

With empty __init__.py this can also be achieved by reading test.py

 import subpackage.hello_world subpackage.hello_world.do_something() 

or even

 from subpackage.hello_world import do_something do_something() 

Ultimately, the best tool to help you understand is a clear understanding of how imports work and how its various forms have an impact on the imported namespace.

+10
source share

You must first understand how import works:

 import test.submodule.do_something 

submodule try to load do_something from a submodule that is loaded from test .

You want to download something from subpackage , so start with this:

 import subpackage 

Pictured, subpackage/__init__.py loaded.

Now you need the do_something() function, which is located in the file ("module") hello_world.py . Easy:

 from subpackage.hello_world import do_something 

And you're done! Just read this line aloud, it does exactly what it says: import do_something from the hello_world module, which is in the subpackage package.

Try in test.py

 from subpackage.hello_world import do_something do_something() 

It should work fine.

Now the second problem:

__init__.py will not be called in package/ , since you are not using package/ as a package. __init__.py will be used if you import package/ or anything in it, for example:

 from package import test 

Otherwise, it will not be loaded at all.

However, if you want to load do_something() when importing a subpackage, put from submodule.hello_word import do_something in subpackage/__init__.py , and then do import subpackage

+1
source share

This is an absolute solid rule in Python that a name should always be defined or imported inside the module in which you use it. Here you never import anything inside test.py - since the error says do_something is undefined.

Even if your package/__init__.py was executed (which, as others have pointed out, this is not the case), your code will still not work the way it is, because do_something import must be done inside test.py if you want reference it in this file.

+1
source share

All Articles