I'm sure there's an answer to this question somewhere on SO, but I can't seem to find the right search terms to ferret it out.
Source file layout:
./mycode.py
./protocols/__init__py (empty)
./protocols/prot1.py
./protocols/prot2.py
./protocols/prot3.py
./protocols/prot1.py:
class Prot1:
@classmethod
def getAddress(cls, data):
return f(data)
Similar for Prot2 and Prot3, but the return value is calculated differently in each class.
mycode.py:
import protocols
self.protocolClasses = {
"1" : Prot1,
"2" : Prot2,
"3" : Prot3
}
protocol = "1" # just for the example
f = self.protocolClasses[protocol].getAddress(somedata)
That seems right to me, but Python gives an error:
NameError: global name 'Prot1' is not defined
The line number referenced is:
"1" : Prot1,
What am I missing?
Edit: If I use the following syntax:
"1" : protocols.prot1.Prot1,
I get:
AttributeError: 'module' object has no attribute 'prot1'
If I use:
"1" : protocols.Prot1,
I get:
AttributeError: 'module' object has no attribute 'Prot1'
1 Answer 1
Having directory structure as yours you have to fix imports.
Here is what will work:
from protocols.prot1 import Prot1
from protocols.prot2 import Prot2
from protocols.prot3 import Prot3
self.protocolClasses = {
"1" : Prot1,
"2" : Prot2,
"3" : Prot3
}
protocol = "1" # just for the example
f = self.protocolClasses[protocol].getAddress(somedata)
Or you can use ./protocols/__init__py and add next lines in it:
from prot1 import Prot1
from prot2 import Prot2
from prot3 import Prot3
This way you will be able to do imports like:
from protocols import Prot1, Prot2, Prot3
Now why is that?
It's because protocols is a Python package (by having __init__.py file in it) and prot1, prot2, prot3 are Python modules. In those modules you have defined classes. That is why you need to use full namespace i.e. protocols.prot1.Prot1 or from protocols.prot1 import Prot1.
3 Comments
protocols/__init__.py you will not be able to from protocols.prot1 import Prot1 at all. Alternative is to have protocols.py instead of directory, and have all classes defined in it.
Prot1? You meanprotocols.prot1.Prot1. You can also go withfrom protocols.prot1 import Prot1if you're going to use it in more places.