how to arrange classes in .py files?

K

Kent

Hi all,

I work with Java. Recently I read some about python, and it is really
impressive. So i decide to learn it in my spare time by a small
application. But i got a question about the python classes. Didn't
find any help with Google.

In java, usually a .java file contains One Class. I read some python
codes, I found one py file can have many classes and functions. Is
there any convention how to manage python classes into .py files?

Now I just deal with my little application exactly in Java style:
package: gui, service, dao, entity, util (from the package name, you
can see the MVC pattern)
gui: wxPython classes
service: business logic, transaction mgmt etc.
dao: Data access classes
entity: "pojo"s
util: some handy utility classes

later VO classes/package may be involved as well.

In above packages, each .py file contains one python class. And
ClassName = Filename

not sure about the right code structure of python oop.

Can anyone give some hint on it? would be great with reason.

Thanks in advance.


regards,

Kent
 
T

Terry Reedy

Kent said:
In above packages, each .py file contains one python class. And
ClassName = Filename

not sure about the right code structure of python oop.

Group related objects into one module. People of course differ on
lumping versus splitting.
Can anyone give some hint on it? would be great with reason.

If classname == filename and you have lots of classes, then you have
lots of entries in your directory and lots of import statements and lots
of entries in sys.modules and the only way to group things on the disk
is to add a directory, but there would still be no grouping of possibly
100s of modules.

Also, Python has lots of object classes other than classes, and many of
these other classes may reasonably be instanced in a module.

A modules is a namespace is a directory. A class, by the way, is a
namespace with behavior. So the reason to group related things in a
module may be similar to the reason to group related things in a class.
(Although I have read that some Java classes only 'group' one thing,
which is generally silly from a Pythonic viewpoint.)

tjr
 
B

bearophileHUGS

Kent:
Now I just deal with my little application exactly in Java style:
package: gui, service, dao, entity, util

If those things are made of a small enough number of sub things and
such sub things are small enough, then you may use a single module for
each of those Java packages (or even less).

My suggestion: try to write as little code as possible.
With practice you will see your Python code shrink a lot compared to
the Java one (but don't overdo it, one of the main qualities of Java
is long-term maintainability of code. And you can't do it if you write
Python in a code-golf-style :) ).

Bye,
bearophile
 
D

David L. Jones

... Is
there any convention how to manage python classes into .py files?

...
In above packages, each .py file contains one python class. And
ClassName = Filename

...
Can anyone give some hint on it? would be great with reason.

Overall, I don't think there is a single convention that anyone can
point to and everyone will at least acknowledge as convention.

If you have multiple single-class files, then you will have
unnecessary redundancy referencing the classes from outside:

# Module structure: mymodule/
# __init.py__
# someclass.py
import mymodule
c = mymodule.someclass.someclass()

You can get around this with a Java-like statement:

# Same module structure
from mymodule.someclass import someclass # or from ... import *
c = someclass()

but you lose namespacing which can make code more difficult to read. I
think that this Java-style approach of pulling everything into the
current namespace is quite silly, since Python's module structure was
specifically designed in large part not to work like this. (Commence
flaming.)

I tend to think in terms of coupling and cohesion. Within an
application, any classes, functions, data, etc. that are tightly
coupled are candidates to live in the same file. If you have a set of
classes that all inherit from a common set of base classes, then you
should probably consider putting the base and inherited classes
together in a file. That puts them in the same namespace, which makes
sense.

Cohesion is the flip side: if a class is large, even if it is somewhat
coupled to other classes, it should probably go in its own file. In
general, use coupling as a guide to put more things into a single
file, and cohesion as a guide to break out parts into multiple files.

D
 
K

Kent

Overall, I don't think there is a single convention that anyone can
point to and everyone will at least acknowledge as convention.

If you have multiple single-class files, then you will have
unnecessary redundancy referencing the classes from outside:

  # Module structure:  mymodule/
  #                      __init.py__
  #                      someclass.py
  import mymodule
  c = mymodule.someclass.someclass()

You can get around this with a Java-like statement:

  # Same module structure
  from mymodule.someclass import someclass  # or from ... import *
  c = someclass()

but you lose namespacing which can make code more difficult to read. I
think that this Java-style approach of pulling everything into the
current namespace is quite silly, since Python's module structure was
specifically designed in large part not to work like this. (Commence
flaming.)

I tend to think in terms of coupling and cohesion. Within an
application, any classes, functions, data, etc. that are tightly
coupled are candidates to live in the same file. If you have a set of
classes that all inherit from a common set of base classes, then you
should probably consider putting the base and inherited classes
together in a file. That puts them in the same namespace, which makes
sense.

Cohesion is the flip side: if a class is large, even if it is somewhat
coupled to other classes, it should probably go in its own file. In
general, use coupling as a guide to put more things into a single
file, and cohesion as a guide to break out parts into multiple files.

D

thanks you guys' explaination. I did some refactory on my codes. Now
it look's like:

myapp/ # this is a package, it is the root package
- gui/ # this is package, contains all gui related modules
- mainFrame.py


- dao.py # all daos are in this module
- service.py # all service classes, responsible for handling DB
connections, Txn mgmt, and Business logic Task (calling daos)
- entity.py # like 'pojo's, in java,
- util.py # utils
- myapp.py # start main script


with this structure, import statements were *significantly*
reduced. :)
 
M

Michael Torrie

Kent said:
In java, usually a .java file contains One Class. I read some python
codes, I found one py file can have many classes and functions. Is
there any convention how to manage python classes into .py files?

In python we have a real name space, the primary unit being the
"module." Think of a module as a singleton really, with any code in
module being executed upon import (a sort of constructor). Python
classes are really just objects, so you can put as many related objects
in a module as you want, or is appropriate (more on this later), and
refer to them with the "module.object" notation. If you need to spread
your code that's in one namespace out over several files for clarity and
ease of debugging, you can create a python "package[1]" which consists
of an __init__.py that can pull in various names from other files in the
package into the namespace it is defining. A python package is imported
as if it was a normal module.

How you are organizing your python code is probably fine, but wouldn't
be considered very pythonic and familiar to many python programmers.
Most of us don't want to have to deal with something like:

import mymodule

myobject=mymodule.class.Class()

as that is redundant. Rather, myobject=mymodule.Class() is expected.
Sounds to me like your style of programming may lend itself to using a
python package as an organizational unit for your code.

Typically my modules have the following structure:
- set up any module variables and constants
- exception classes
- internal functions or classes (private to the module)
- public functions or classes
- module-level code to perform any on-load stuff
- an if __name__=="__main__" section for doing unit testing

My modules are typically defined according to function. Common module
names would include config, utilities, etc.

Since the singleton is the pattern that I use the most, I actually
rarely need classes at all in most modules, except to define exceptions
my module will raise. I consider functions in modules to be the
equivalent of methods on a static class. Quite a refreshing break from
the way Java forces me to work. And much cleaner too.

Often as I develop a module, I'll factor out code that's generic out of
the module into its own module. There should be very loose coupling
between modules, and very tight coupling within the module, though not
necessarily... a collection of utility functions are often just
collected in a module for convenience. Coupling is a good indicator of
whether you should factor the code out into its own module. Finally, if
I want to take a group of modules and export a simple, clean, public
interface, I'll wrap the modules in a package.

[1] http://docs.python.org/tutorial/modules.html#packages
 
T

Terry Reedy

Kent said:
thanks you guys' explaination. I did some refactory on my codes. Now
it look's like:

myapp/ # this is a package, it is the root package
- gui/ # this is package, contains all gui related modules
- mainFrame.py


- dao.py # all daos are in this module
- service.py # all service classes, responsible for handling DB
connections, Txn mgmt, and Business logic Task (calling daos)
- entity.py # like 'pojo's, in java,
- util.py # utils
- myapp.py # start main script

Really clear.
with this structure, import statements were *significantly*
reduced. :)

Bingo!

tjr
 

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
474,434
Messages
2,571,690
Members
48,796
Latest member
Greg L.

Latest Threads

Top