When you call import models.Sentence
, you're telling Python to load your Sentence.py
file, and put all of its variables inside the models.Sentence
namespace. Thus, your Sentence
class also becomes listed under models.Sentence
, and so it becomes models.Sentence.Sentence
.
In terms of using __init__.py
, you can put something like this in that file:
from .Sentence import * # or import Sentence if that's all you want
and then in your base.py
:
import models
my_sentence = models.Sentence("arg")
What your __init__.py
does now is load everything from Sentence.py
into its own namespace, instead of models.Sentence
. So that means your Sentence
class is no longer models.Sentence.Sentence
, and is now just models.Sentence
.
NB: If you want to be able to run your __init__.py
file as the main file, or run any script inside the models
folder, you should put this code in __init__.py
instead:
import __main__, os
if os.path.dirname(__main__.__file__) == os.path.dirname(__file__):
# executed script in this folder
from Sentence import *
else:
# executed script from elsewhere
from .Sentence import *
EDIT:
To understand why you need to use models.Sentence.Sentence('arg')
, let's look at a clearer example:
Suppose I have a module I've made called package
. In that module, I have sub-module this_useful_part.py
.
This is the folder structure:
main.py
package
this_useful_part.py
In this_useful_part.py
:
class my_very_helpful_class:
pass
In main.py
:
import package.this_useful_part
my_instance = package.this_useful_part.my_very_helpful_class()
(I realise I may not have chosen the best names)
The reason I require package.this_useful_part.my_very_helpful_class
, and you require models.Sentence.Sentence
is because the class is not the file, but stored within the file, and the file is not the folder, but stored within the folder.
The ways around this:
You can put the class definition inside __init__.py
, so when you import models
, it can be referenced as models.Sentence
.
You do as I did above, where you import everything from Sentence.py
, so that the class definition is also stored directly inside the __init__.py
file, and so it can be referenced as models.Sentence
.
I hope this clears things up.
EDIT 2:
After a bit more research, I found that it is possible to make a module callable. (From here)
You don't require an __init__.py
file if you change the code in your Sentence.py
file to this:
import sys
class Sentence:
def __init__(self, arg):
self.arg = arg
sys.modules[__name__] = Sentence
You can now do
import models.Sentence
my_sentence = models.Sentence('arg')
Sorry for my mistake.