what's the general way of separating classes?

J

John Salerno

From my brief experience with C#, I learned that it was pretty standard
practice to put each class in a separate file. I assume this is a
benefit of a compiled language that the files can then be grouped together.

What I'm wondering is how is this normally handled in Python? Is it
normal for classes to be put in separate modules? It seems like this can
get out of hand, since modules are separate from one another and not
compiled together. You'd end up with a lot of import statements.

Are related classes put into a single module then? Or is there some
recommended method for how to handle this?

Thanks.
 
F

Felipe Almeida Lessa

Em Seg, 2006-03-20 às 15:42 +0000, John Salerno escreveu:
Are related classes put into a single module then? Or is there some
recommended method for how to handle this?

IMHO, if they can be put on the same file without creating a huge one
(3000+ lines), then do it. If you can't, then instead of creating a
huge:

program/module.py

You can do lots of

program/modules/*.py

And create an program/modules/__init__.py that have something like

from program.modules.class1 import class1
from program.modules.class2 import class2

And, in the rest of your program, you can import class1 and class2 by
just issuing

from program.modules import class1, class2

HTH,
 
J

John Salerno

Felipe said:
And create an program/modules/__init__.py that have something like

from program.modules.class1 import class1
from program.modules.class2 import class2

I'm not sure I understand the point of those two lines, if you are going
to then do this:
And, in the rest of your program, you can import class1 and class2 by
just issuing

from program.modules import class1, class2

How does the __init__ file help if you are still individually importing
class1 and class2 in each other module of your program?
 
R

Roy Smith

John Salerno said:
From my brief experience with C#, I learned that it was pretty standard
practice to put each class in a separate file. I assume this is a
benefit of a compiled language that the files can then be grouped together.

What I'm wondering is how is this normally handled in Python? Is it
normal for classes to be put in separate modules? It seems like this can
get out of hand, since modules are separate from one another and not
compiled together. You'd end up with a lot of import statements.

Are related classes put into a single module then? Or is there some
recommended method for how to handle this?

There are two different issues here. One is how you organize your
source code, the other is what API you expose to the user.

From the source code point of view, I will generally put a single
class in each file, but there are exceptions (no pun intended). If
I've got a bunch of very closely related classes, especially if
they're small, I'll put more than one class in a file. How small is
small? There's no hard number, but anything that's got more than a
couple of methods is probably not small. Exception classes certainly
don't get their own file; they get put in the module where they make
the most sense.

From the API point of view, just because you split your classes up
into multiple modules, doesn't mean the user has to see that
complexity. Have one top level module which imports the others. The
user only has to import the top level one.

There's no magic answer here.

To give you a real example, I just took a look at a recent project I
did. I've got 8 python source files, totalling 1505 lines. I define
14 classes, of which 7 are exception classes. My top level module
(the one a user would import) has no classes defined in it; it imports
the other modules and has a bunch of factory functions. I looked at
the one file that contains two real classes; one of them is
essentially an inner class and has only two methods; __init__() and
__call__(), both of which are trivial.
 
F

Felipe Almeida Lessa

Em Seg, 2006-03-20 às 16:01 +0000, John Salerno escreveu:
I'm not sure I understand the point of those two lines, if you are going
to then do this:


How does the __init__ file help if you are still individually importing
class1 and class2 in each other module of your program?

Ermmm... Maybe I should give a bigger example? What's better, this

from program.modules.class1 import class1
from program.modules.class2 import class2
from program.modules.class3 import class3
from program.modules.class4 import class4
from program.modules.class5 import class5
from program.modules.class6 import class6
from program.modules.class7 import class7
from program.modules.class8 import class8
from program.modules.class9 import class9
from program.modules.class10 import class10
from program.modules.class11 import class11
from program.modules.class12 import class12
from program.modules.class13 import class13
from program.modules.class14 import class14
from program.modules.class15 import class15
from program.modules.class16 import class16
from program.modules.class17 import class17
from program.modules.class18 import class18
from program.modules.class19 import class19
from program.modules.class20 import class20

or this

from program.modules import (class1, class2, class3, class4,
class5, class6, class7, class8,
class9, class10, class11, class12,
class13, class14, class15, class16,
class17, class18, class19, class20,
class21, class22, class23, class24,
class25, class26, class27, class28,
class29, class30, class31, class32,
class33, class34, class35, class36,
class37, class38, class39, class40)

???

If you mean doing "from program.modules import *" of course you *can*,
but you *shouldn't*. It makes your code a mess after some time.
 
B

bruno at modulix

John said:
From my brief experience with C#, I learned that it was pretty standard
practice to put each class in a separate file. I assume this is a
benefit of a compiled language that the files can then be grouped together.

What I'm wondering is how is this normally handled in Python? Is it
normal for classes to be put in separate modules?

Depends on the size of the classes... I tend to write as small as
possible classes, so I usually have a bunch of closely related classes
(and functions and constants...) in a module.
It seems like this can
get out of hand, since modules are separate from one another and not
compiled together. You'd end up with a lot of import statements.

Sorry, but I don't see the correlation between compilation and import
here ?

As for imports, you have to import each needed symbol anyway - from
module import * is really bad practice IMHO, except in the shell, and
then it's just a matter of packaging related modules together (which
should be the case anyway) and setting the __all__ attribute of the
package __init__.
Are related classes put into a single module then? Or is there some
recommended method for how to handle this?

cf above. And/or browse the standard lib's sources - you know, it's Open
Source !-)

HTH
 
J

John Salerno

bruno said:
Sorry, but I don't see the correlation between compilation and import
here ?

I meant that in a language like C#, which compiles all the separate
files into one program, it is not necessary to have the equivalent of an
import/include type of statement. You can just refer to the classes from
any other file. But in Python, without this behavior, you must
explicitly import any external files. At least, I think I have that
correct in my head. :)
 
I

I V

John said:
How does the __init__ file help if you are still individually importing
class1 and class2 in each other module of your program?

Felipe's example is a little confusing because he uses the same name
for the module and the class. Here's another example:

--- package/class1.py ---

class C1:
pass

--- package/class2.py ---

class C2:
pass

--- package/__init__.py ---

from class1 import C1
from class2 import C2

--- end ---

Now, in your code you can do:

import package

c = package.C1()

If you hadn't included the lines in __init__.py, you would have to
write:

import package

c = package.class1.C1()
 
J

John Salerno

I said:
Now, in your code you can do:

import package

c = package.C1()

If you hadn't included the lines in __init__.py, you would have to
write:

import package

c = package.class1.C1()

Ah, this makes sense! Thanks! :)
 
I

Ido Yehieli

or you can write the (slightly dangerous) following:

import os
for file in os.listdir("/path/to/modules"):
if file.endswith(".py"):
exec("from "+file[:-3]+" import *")
 
B

Ben Cartwright

John said:
I meant that in a language like C#, which compiles all the separate
files into one program, it is not necessary to have the equivalent of an
import/include type of statement.

Er? Surely you've used C#'s "using" statement? Apples and oranges,
but:

C#'s "using Foo.Bar;" is roughly analogous to Python's
"from foo.bar import *".

C#'s "int x = Foo.Bar.f();" is roughly analogous to Python's
"import foo.bar; x = foo.bar.f()".
You can just refer to the classes from
any other file.

Iff they're in the same namespace. You can have multiple namespaces in
the same .NET assembly, you know.
But in Python, without this behavior, you must
explicitly import any external files.

That's true. Each Python file is essentially its own namespace. And
when, say, __init__.py does a "from submodule import *" it essentially
merges submodule's namespace into its own.

--Ben
 
J

John Salerno

Ben said:
Er? Surely you've used C#'s "using" statement?

Well yes, but really that's very different. 'Using' statements are
solely for the purpose of convenience so you don't have to qualify
classes with namespaces. They aren't necessary to actually *use* those
classes.

(The true 'include' functionality comes in the References, which are
shared across all files on account of them being compiled together.)
Iff they're in the same namespace. You can have multiple namespaces in
the same .NET assembly, you know.

Yes, true. I was just thinking of a program all contained in one namespace.
 

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

Forum statistics

Threads
474,201
Messages
2,571,049
Members
47,655
Latest member
eizareri

Latest Threads

Top