I have this directory/file hierarchy:
python/
test.py
t3io/
agent.py
common.py
The content of the files is:
python/test.py
import t3io.agent
t3io = t3io.Agent( )
python/t3io/common.py
class Exit:
__init__( self ):
pass
class Signal:
__init__( self ):
pass
python/t3io/agent.py
from . common import *
class Agent:
def __init__( self ):
pass
In C++, the physical container (file with the code) is independent of the logical container (the namespace
). I would like to get something similar in python; from directory python
, try
$>python test.py
AttributeError: module 't3io' has no attribute 'Agent'
That is, in python, I need to use an additional wrapper :
t3io = t3io.agent.Agent( )
- How can I avoid the use of the file name when using symbols present in it?
You have several alternatives to achieve what you want, depending on what you have in mind:
Avoid an "additional level"
In
test.py
you can just put:That exactly the syntax you had works
That is, it works to put
t3io = t3io.Agent()
The first thing to say is that perhaps calling the variable
t3io
, since that is the same name as the module/package you are importing, does not seem like the best idea to me, as it can cause all kinds of confusion. In any case, the following would work, although it is a hack that I advise against:The syntax
import X as Y
allows you to "rename" the namespace so that it is not necessarily the same as the imported module. In this way the module that we import (t3io.agent
) is renamed ast3io
, so you can do it latert3io.Agent()
. In any case, since you then assign the result to a variablet3io
, you are losing that namespace and in the rest of the script you will no longer be able to refer tot3io
to access any more classes or variables from the imported module, as itt3io
will be from that point the variable that contains the objectAgent
.Importing sub-modules in the "main" package
The folder
t3io
is technically a "package" because it contains several submodules inside it. Being a package, it can contain a file called__init__.py
(in fact, the existence of that file was mandatory in previous versions of python, even if it was empty, as a "marker" that this folder was a package).If that file exists, it will be executed when from the main program you do
import t3io
. Therefore, inside that__init__.py
you can makeimport
other classes that you want to make "visible" from the top level of the package, even if they are implemented in submodules.That is, you can make it
t3io/__init__.py
contain the following:And then in the main program you can do:
The will
import t3io
executet3io/__init__.py
and create the namespacet3io
with the result. As a consequence that namespace will containAgent
because in__init__.py
it we have imported it from its sub-module.I think this solution is the best (discounting that it has the same problem mentioned above regarding the variable you have called
t3io
, as well as the package)