Help with modules/packages.

  • Thread starter Christopher J. Bottaro
  • Start date
C

Christopher J. Bottaro

Hello,
I want to be able to say stuff like "import CJB.ClassA" and "import
CJB.ClassB" then say "c = CJB.ClassA()" or "c = CJB.ClassB()". CJB will be
a directory containing files "ClassA.py" and "ClassB.py".

Now that I think about it, that can't work because Python allows you import
different things from the same module (file). If I said "import
CJB.ClassA", I'd have to instantiate ClassA like "c = CJB.ClassA.ClassA()".

I guess I could say "from CJB.ClassA import ClassA", but then I'd
instantiate like "c = ClassA()". What I really want is to say "c =
CJB.ClassA()"...is that possible?

Is my understand of modules/packages correct or am I way off?

Thanks for the help.
 
S

Steve Holden

Christopher said:
Hello,
I want to be able to say stuff like "import CJB.ClassA" and "import
CJB.ClassB" then say "c = CJB.ClassA()" or "c = CJB.ClassB()". CJB will be
a directory containing files "ClassA.py" and "ClassB.py".

Now that I think about it, that can't work because Python allows you import
different things from the same module (file). If I said "import
CJB.ClassA", I'd have to instantiate ClassA like "c = CJB.ClassA.ClassA()".

I guess I could say "from CJB.ClassA import ClassA", but then I'd
instantiate like "c = ClassA()". What I really want is to say "c =
CJB.ClassA()"...is that possible?

Is my understand of modules/packages correct or am I way off?

Thanks for the help.
Your understanding appears to be roughly correct, but you are
overlooking the possibility that the package could manage its own namespace.

One thing you could try is, in the __init__.py for CJB, do

from ClassA import ClassA
from ClassB import ClassB

You can then refer to the classes using the names you want.

regards
Steve
 
S

Steve Holden

Christopher said:
Hello,
I want to be able to say stuff like "import CJB.ClassA" and "import
CJB.ClassB" then say "c = CJB.ClassA()" or "c = CJB.ClassB()". CJB will be
a directory containing files "ClassA.py" and "ClassB.py".

Now that I think about it, that can't work because Python allows you import
different things from the same module (file). If I said "import
CJB.ClassA", I'd have to instantiate ClassA like "c = CJB.ClassA.ClassA()".

I guess I could say "from CJB.ClassA import ClassA", but then I'd
instantiate like "c = ClassA()". What I really want is to say "c =
CJB.ClassA()"...is that possible?

Is my understand of modules/packages correct or am I way off?

Thanks for the help.
Your understanding appears to be roughly correct, but you are
overlooking the possibility that the package could manage its own namespace.

One thing you could try is, in the __init__.py for CJB, do

from ClassA import ClassA
from ClassB import ClassB

You can then refer to the classes using the names you want.

regards
Steve
 
M

M.E.Farmer

Hello Christopher,
You probably know this but I will mention it here for
completeness, if you want to be able to make a dir a package you also
need to add an __init__.py in the folder you wish to import from. The
__init__.py makes the dir a package.
Example:
<dir> CJB
<file> __init__.py
<file> ClassA.py
I want to be able to say stuff like "import CJB.ClassA" and "import
CJB.ClassB" then say "c = CJB.ClassA()" or "c = CJB.ClassB()". CJB will be
a directory containing files "ClassA.py" and "ClassB.py".
Let us clarify a few things first.
"import CJB.ClassA" imports MODULE ClassA from PACKAGE CJB into the
namespace, but it is a MODULE and therefore not callable ;)
"c = CJB.ClassA()" is attempting to call the module ClassA , but you
want to call a ClassA CLASS in the ClassA MODULE
"c=CJB.ClassA.ClassA()"
BTW the names you have used makes this less understandable.
Maybe CJB.ModuleA.ClassA() would make this clearer.
Now that I think about it, that can't work because Python allows you import
different things from the same module (file). If I said "import
CJB.ClassA", I'd have to instantiate ClassA like "c = CJB.ClassA.ClassA()".

I guess I could say "from CJB.ClassA import ClassA", but then I'd
instantiate like "c = ClassA()". What I really want is to say "c =
CJB.ClassA()"...is that possible?

Yes it is possible.
I will show you how, BUT I must mention that it makes it VERY UNCLEAR
where the code comes from. The beauty of packages is code seperation
and modularity, and you are going to find aliasing makes for an
interesting debug session trying to guess where it all went wrong. You
should probably just bite the bullet and use
name = package.module.class it is easier to grasp 1 year from now and
makes it easier for others to read. The time you saved typing the
extra letters is less then the time you will spend looking at your
code. READABILITY counts.

Ok now onto the imports.
This is just *A* way to do it, there are others.
In your __init__.py you need to do your imports and aliasing:

# __init__.py
# this __init__.py file makes this dir a python package
import CJB.ClassA
import CJB.ClassB
classA = CJB.ClassA.ClassA
classB = CJB.ClassB.ClassB
# end of __init__.py

Now all you do is import.

import CJB
dir(CJB)
CJB.ClassA()
CJB.ClassB()
Is my understand of modules/packages correct or am I way off?

Not to far off :)
Thanks for the help.

HTH,
M.E.Farmer
 
N

Nick Coghlan

Christopher said:
Hello,
I want to be able to say stuff like "import CJB.ClassA" and "import
CJB.ClassB" then say "c = CJB.ClassA()" or "c = CJB.ClassB()". CJB will be
a directory containing files "ClassA.py" and "ClassB.py".

Now that I think about it, that can't work because Python allows you import
different things from the same module (file). If I said "import
CJB.ClassA", I'd have to instantiate ClassA like "c = CJB.ClassA.ClassA()".

I guess I could say "from CJB.ClassA import ClassA", but then I'd
instantiate like "c = ClassA()". What I really want is to say "c =
CJB.ClassA()"...is that possible?

Is my understand of modules/packages correct or am I way off?

To collapse the namespace locally (i.e. in the module you're currently writing,
rather than in the package you're referring to), you can use a convention like:

from CJB.ModuleA import ClassA as CJB_A
from CJB.ModuleB import ClassB as CJB_B

This also has the advantage of being slightly faster - each '.' in a name
represents another namespace lookup, which happens at run time, not compile
time. This can end up mattering if the lookup is being done inside a loop.

The above idiom gives you a reference directly to the classes you want to use,
thus allowing them to be found directly in the module's own dictionary.

Cheers,
Nick.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top