Contents :
tutorials/maindir/
├── dir1
│ ├── file11.py
│ ├── file12.py
│ ├── __init__.py
│ └── __pycache__
│ ├── file11.cpython-36.pyc
│ └── __init__.cpython-36.pyc
├── dir2
│ ├── file21.py
│ ├── file22.py
│ └── __init__.py
├── file1.py
├── file2.py
├── __init__.py
└── __pycache__
├── file1.cpython-36.pyc
└── __init__.cpython-36.pyc
now I have a code giving me following output which I don't get.
Code ::
print("--main--", dir())
from tutorials.maindir import *
print("--main--", dir())
OutPut ::
--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
tutorials
tutorials.maindir
tutorials.maindir.dir1
--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'dir1', 'tutorials']
I don't get why dir1
and tutorials
are there in the dir()
's output.
maindir.__init__.py
's Code :
print(__name__)
import tutorials.maindir.dir1.file11
EDIT 1 ::
So if the code is :
print("--main--", dir())
import tutorials.maindir.dir1.file11
print("--main--", dir())
The output is :
--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
tutorials
tutorials.maindir
tutorials.maindir.dir1
--main-- ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'tutorials']
When you run an import
you are causing __init__.py
to run. [source]
If __all__ is not defined, the statement from sound.effects import * does not import all submodules from the package sound.effects into the current namespace; it only ensures that the package sound.effects has been imported (possibly running any initialization code in __init__.py) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by __init__.py. It also includes any submodules of the package that were explicitly loaded by previous import statements.
In your case, this includes another import
:
import tutorials.maindir.dir1.file11
That causes certain things to be bound to the local namespace: [source]
define a name or names in the local namespace for the scope where the import statement occurs.
And more specifically:
If the module being imported is not a top level module, then the name of the top level package that contains the module is bound in the local namespace as a reference to the top level package. The imported module must be accessed using its full qualified name rather than directly
So in your case, tutorials
is the top level module which was already imported, and dir1
is the imported package (chosen by being the parent name).
And then finally dir()
is going to: [source]
Without arguments, return the list of names in the current local scope. With an argument, attempt to return a list of valid attributes for that object.
So to your comment, the top level package and the individual names defined in the import statements are bound to the local namespace which is why they show up, but maindir is not a top level package or an imported package so it does not show up.
EDIT: (and additional information)
First, I'd recommend doing some technical reading on a few things if all of this is super interesting to you or relevant:
Those PEPs discuss a lot of how modern import works and some of the special and weird parts of it, as well as how to form it to do what you need it to do in your use case.
On to your edit question:
When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned. [source]
So for your basic long import statement, it will put the top level module into the namespace.
If the list of identifiers is replaced by a star ('*'), all public names defined in the module are bound in the local namespace for the scope where the import statement occurs. [source]
import name
gives you nameimport name.one
gives you nameimport name.one.two
gives you namefrom name import one
gives you onefrom name import one as two
gives you two
Now back to your example:from tutorials.maindir import *
will first import the top level module. Then __init__.py
will run which does another import. That import will skip the top level module since that is already imported, and will move down to the package and then import as the name of the parent, or essentially the right most .
it will move left one term and import as that name. [code].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With