How to structure packages

B

bclark76

I'm learning python, and was playing with structuring packages.

Basically I want to have a package called mypackage that defines a
number of classes and functions.


so I create:

mypackage
__init__.py
myfunc.py
MyClass.py


my __init__.py is blank.

my MyClass.py looks like:

import blah

class MyClass(blahblah):
blah
blah
blah


then I have a run.py that looks like

from mypackage import MyClass


x = MyClass()


This doesn't work because MyClass is mypackage.MyClass.MyClass.
There's this MyClass module 'in the way'.


I'm trying to follow the rule that every file defines only one class.
I could define MyClass in __init__.py, but then what if I wanted to
define more classes in the mypackage package? My one class per file
rule goes out the window.

Is this rule wrongheaded, or is there another way to do this?


Thanks.
 
P

Peter Otten

bclark76 said:
I'm learning python, and was playing with structuring packages.

If you are coming from Jave you have to unlearn a thing or two.
Basically I want to have a package called mypackage that defines a
number of classes and functions.
I'm trying to follow the rule that every file defines only one class.
I could define MyClass in __init__.py, but then what if I wanted to
define more classes in the mypackage package? My one class per file
rule goes out the window.

Is this rule wrongheaded,
Yes.

or is there another way to do this?

I recommend that you always start out with a module. Once that becomes
unwieldy you can convert it into a package. Let's assume that

mystuff.py

contains a MyClass that you want to move into a separate file. You get the
following files:

mystuff
__init__.py
descriptivename.py # MyClass here

Note that all filenames are lowercase. If you add the line

from .descriptivename import MyClass

to __init__.py you can continue to import and use MyClass with the statement

from mystuff import MyClass
m = MyClass()

or

import mystuff
m = mystuff.MyClass()

The disadvantage is of course that mystuff.descriptivename will always be
imported, even if you don't need the part of the mystuff package defined
there.

You may also have a look into unittest as an example of a module that was
recently converted into a package. Classes and functions are grouped into
submodules by their functionality rather than employing Java's mechanical
one-class-per-file pattern.
 
R

rantingrick

I'm learning python, and was playing with structuring packages.

Basically I want to have a package called mypackage that defines a
number of classes and functions.

so I create:

mypackage
    __init__.py
    myfunc.py
    MyClass.py

Don't tell me you create a module called myfunc.py??? Stuff that
function in __init__! Also don't name modules MyClass either. Both the
spelling and grammar is incorrect. ALL modules use lowercase (and only
integrate underscores in the most dire of need!)

geom
__init__.py
vector3d.py
point3d.py
transformation.py

from geom.transformation import Transformation
from geom.vector3d import Vector3d
from geom.point3d import Point3d

or alternatively:

geom
__init__.py
from __vector3d import Vector3d
from __point3d import Point3d
from __transformation import Transformation
__vector3d.py
__point3d.py
__transformation.py

from geom import Transformation
from geom import Vector3d
from geom import Point3d

Although this method can be brittle due to the fact that one buggy
module can break all the imported code in the __init__ module. I
usually opt for specifying the module in the import path.
 
L

Littlefield, Tyler

I'm learning python, and was playing with structuring packages.

Basically I want to have a package called mypackage that defines a
number of classes and functions.


so I create:

mypackage
__init__.py
myfunc.py
MyClass.py


my __init__.py is blank.

my MyClass.py looks like:

import blah

class MyClass(blahblah):
blah
blah
blah


then I have a run.py that looks like

from mypackage import MyClass


x = MyClass()


This doesn't work because MyClass is mypackage.MyClass.MyClass.
There's this MyClass module 'in the way'.
You can use the __init__.py to promote that class up. so:
from myclass import myclass
So that means that myclass will just be in mypackage.myclass, and thus
your from mypackage import myclass would work perfectly. I'm not sure if
this is how you're supposed to do it, but it works.
I'm trying to follow the rule that every file defines only one class.
I could define MyClass in __init__.py, but then what if I wanted to
define more classes in the mypackage package? My one class per file
rule goes out the window.

Is this rule wrongheaded, or is there another way to do this?


Thanks.


--

Take care,
Ty
Web: http://tds-solutions.net

Sent from my toaster.
 
W

Westley Martínez

First of all MyClass.py should be renamed to myclass.py. Module names
should be lowercase. Secondly, put this in __init__.py:

from .myclass import MyClass

and there you go.
 
S

Steven D'Aprano

Peter said:
Classes and functions are grouped into
submodules by their functionality rather than employing Java's mechanical
one-class-per-file pattern.

Surely it's an anti-pattern?

I suppose "one class per file" might be useful for those using an editor
with no search functionality. Other than that, is there any justification
for this rule? Any Java fans want to defend this?

If "one class per file", why not "one method per class" too? Why is the
second rule any more silly than the first?
 
C

Chris Angelico

Surely it's an anti-pattern?

I don't think that's true; Java merely enforces one _public_ class per
source file. A file can have non-public classes, although one .class
file has only one class in it (so javac will sometimes make multiple
object files from one source file). I'm not wholly sure of the
significance of public classes, though, and whether or not it's
possible to do your logical grouping and just let them be non-public.

BTW, I am not a Java fan, and I don't have any defense prepared. I
haven't actually written any serious Java code for a number of years.
Used to use it back when IBM reckoned that Java would be the big thing
that sells OS/2.

ChrisA
 
D

Dan Sommers

I suppose "one class per file" might be useful for those using an editor
with no search functionality. Other than that, is there any
justification for this rule? Any Java fans want to defend this?

Back in the dark ages known as the 1980s, we had a one-C-function-per-
file rule on a project with tens of thousands of C functions. The big
benefit was that we always knew which source file contained which
function. Computers could search a directory tree much more quickly than
that much source code. (The exception was the so-called Information
Cluster, a collection of functions surrounding a data store, the
predecessor to the modern day object-with-state and/or closure).

Not a Java fan'ly yours,
Dan
 
J

Jonathan Hartley

Steven D'Aprano wrote:

Other than that, is there any justification
for this rule? Any Java fans want to defend this?

If "one class per file", why not "one method per class" too? Why is the
second rule any more silly than the first?


Hey. I'm not a Java fan but I'll give it a go.

One method per class is not a good idea because a class is a bunch of code that forms a coherent conceptual bundle of functionality. Often, to providesuch a bundle, it requires more than one method. To split these methods across several classes would be splitting up a single coherent entity, which makes it harder to understand the purpose and identity of the entity, and more fiddly to delineate the boundary between one such entity and the next.

On the other hand, IMHO one class per file is often a good idea. Since a class is a single coherent bundle, then the natural way to split a program into files is often to divide it into these same coherent bundles. Sometimes you have two or more classes that are conceptually very tightly coupled, and it makes sense to gather them up into a single file. However, for me, this is the exception rather than the rule, so in the general case, I usually end up with code that has one class per file. It's only a rule-of-thumb though, and should be broken whenever it seems appropriate.
 
N

Nobody

I suppose "one class per file" might be useful for those using an editor
with no search functionality. Other than that, is there any justification
for this rule? Any Java fans want to defend this?

Not a Java fan, but:

The Java compiler also acts as a "make" program. If it doesn't find
a .class file for a needed class, it will search for the corresponding
..java file and compile that. So to compile a complex program, you only
need to compile the top-level file (e.g. HelloWorld.java), and it will
compile everything which is required. No Makefile is needed, as the
relationship between classes, object files and source files is fixed.
 
C

Chris Angelico

The Java compiler also acts as a "make" program. If it doesn't find
a .class file for a needed class, it will search for the corresponding
.java file and compile that. So to compile a complex program, you only
need to compile the top-level file (e.g. HelloWorld.java), and it will
compile everything which is required. No Makefile is needed, as the
relationship between classes, object files and source files is fixed.

If that's the entire benefit, then I think this is a rather hefty
price to pay for the elimination of a makefile. Oh wow, I can type
"javac MyClass.java" and it picks up all the others! If you're
dividing a project into multiple files already, is it that hard to
have one more that defines the relationships between the others?

Chris Angelico
 
N

Nobody

If that's the entire benefit, then I think this is a rather hefty
price to pay for the elimination of a makefile.

It also eliminates the need for TAGS files, browser database (PDB) files,
etc. Once you know the class name, all of the filenames follow from that.

I suspect that the one-to-one correspondence between classes and .class
files is mostly technical (e.g. Java's security model). The one-to-one
correspondence between class files and source files could probably be
relaxed, but at the expense of complicating the IDE and toolchain.

I never saw it as a problem, given that Java is fundamentally class-based:
there are no global variables or functions, only classes.
 
C

Chris Angelico

I suspect that the one-to-one correspondence between classes and .class
files is mostly technical (e.g. Java's security model). The one-to-one
correspondence between class files and source files could probably be
relaxed, but at the expense of complicating the IDE and toolchain.

One class per object file isn't a problem - you can always .jar your
classes if the proliferation of small files bothers you, and then it's
just a different way of indexing the mound of code.

One class per source file complicates the human's view in order to
simplify the tools'. Not sure that's really worthwhile.
I never saw it as a problem, given that Java is fundamentally class-based:
there are no global variables or functions, only classes.

Yeah... of course you can easily simulate globals with static members
in a dedicated class, but it's slower. THIS, though, is where Java's
security model comes in - you can assign security X to Globals1.class
and security Y to Globals2.class, rather than trying to juggle
security issues in a monolithic "globals" namespace. IMHO it's not
worth the hassle, though. I'd rather just have globals.

ChrisA
 
L

Littlefield, Tyler

It also eliminates the need for TAGS files, browser database (PDB) files,
etc. Once you know the class name, all of the filenames follow from that.

I suspect that the one-to-one correspondence between classes and .class
files is mostly technical (e.g. Java's security model). The one-to-one
correspondence between class files and source files could probably be
relaxed, but at the expense of complicating the IDE and toolchain.

I never saw it as a problem, given that Java is fundamentally class-based:
there are no global variables or functions, only classes.
Sure there are no global variables, but having one class per file is one
of the big things I hate about Java. Sure it keeps things organized, but
that's a bit to much for me.



--

Take care,
Ty
Web: http://tds-solutions.net
The Aspen project: a light-weight barebones mud engine
http://code.google.com/p/aspenmud

Sent from my toaster.
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top