How to organise classes and modules
bruno at modulix
onurb at xiludom.gro
Mon May 15 07:55:02 EDT 2006
Alex wrote:
> Hi, this is my first mail to the list so please correct me if Ive done
> anything wrong.
>
> What Im trying to figure out is a good way to organise my code. One
> class per .py file is a system I like, keeps stuff apart. If I do
> that, I usually name the .py file to the same as the class in it.
First point is that Python doesn't force you to put everything in
classes - if you just need a function, well, make it a function !-)
Also, the common pattern is to put closely related
classes/functions/constants in a same module, and closely related
modules in the same package. Since Python uses a "one file == one
module" scheme, the Javaish "one class per file" idiom leads to overly
complicated imports. And the most common naming scheme for modules is
'alllowercase'.
> File: Foo.py
> ***********************
> class Foo:
> def __init__(self):
> pass
> def bar(self):
> print 'hello world'
>
> ************************
>
> Now, in my other module, I want to include this class. I tried these two
> ways:
>
>>>> import Foo
>>>> Foo.Foo.bar()
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: unbound method bar() must be called with Foo instance as
> first argument (got nothing instead)
>
> Some unbound method error. Have I missunderstood something
Yes:
1/ you usually need to instanciate the class to call an instance method
1/ in this case, bar doesn't need to be a method, since it doesn't
depend on the instance it's called on - a plain old function would be a
better fit.
> or am I on
> the right track here?
>
> I did this to, almost the same thing:
>
>>>> from Foo import Foo
>>>> Foo.bar()
>
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: unbound method bar() must be called with Foo instance as
> first argument (got nothing instead)
>
> One thing that I tried that worked ok was this:
>
>>>> import Foo
>>>> instance=Foo.Foo()
>>>> instance.bar()
>
> hello world
>
> But in my opinion, this is very ugly.
Nope, it's just OO at work.
> Especially if the class names
> are long, like my module/class TileDataBaseManager. But is this the
> "right" way in python?
If you want to import a class from a module and create an instance of
that class, yes.
> Another (ugly) way that Ive considered is the following. Break it out
> of the class,
Which would be a sensible thing to do given the current implementation
of bar().
> save the functions in a file alone,
Nothing prevent you from putting many functions in a same module, you
know...
> import the file
s/file/module/
> and
> treat it like a class:
???
> File: Foo2.py
> ***********************
> def bar(self):
> print 'hello world'
>
> ************************
>
>>>> import Foo2
>>>> Foo2.bar()
>
> hello world
You don't "treat it like a class", you're just using the normal
namespace resolution mechanism. Modules are namespaces, classes are
namespaces, objects (class instances) are namespaces, and the dot is the
lookup operator (ie : somenamespacename.somename means 'retrieve what's
actually bound to name 'somename' in namespace 'somenamespacename').
> Very clean from the outside. I would like something like this. But,
> here, I loose the __init__ function.
Which in the given implementation is just doing nothing.
Ok, I understand that this is just example code. The rule here is:
- if you need per-instance state management, use a class (that you of
course need to instanciate - else you can't have per-instance state !-)
- if you don't need per-instance state management, use a plain function.
> I have to call it manually that
> is, which s not good. Also, maybe the biggest drawback, its no longer
> in a class.
def MyFunc():
pass
print MyFunc.__class__.__name__
Python function's are instances of the function class.
> Maybe its not that important in python but from what Ive
> learned (in c++) object orientation is something to strive for.
print "object orientation".find("class")
Being OO doesn't mean using classes. <troll>And FWIW, there quite enough
procedural Java code around to prove that using classes doesn't mean
doing OO !-) </troll>
> So, to sum it up, I have one class in one file, both with the same
> name. How do I store/import/handle it in a nice, clean and python-like
> manner?
Quit the Javaish "one-class-per-file" idiom, don't bother using classes
when plain old function will do, and you'll be on track...
FWIW, Python's standard lib is open-source, so why not have a look at
the source code to see how it is organized ?
HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list