How to organise classes and modules

A

Alex

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.

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:
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 or am I on
the right track here?

I did this to, almost the same thing:
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:
hello world

But in my opinion, this is very ugly. Especially if the class names
are long, like my module/class TileDataBaseManager. But is this the
"right" way in python?

Another (ugly) way that Ive considered is the following. Break it out
of the class, save the functions in a file alone, import the file and
treat it like a class:

File: Foo2.py
***********************
def bar(self):
print 'hello world'

************************
hello world

Very clean from the outside. I would like something like this. But,
here, I loose the __init__ function. I have to call it manually that
is, which s not good. Also, maybe the biggest drawback, its no longer
in a class. Maybe its not that important in python but from what Ive
learned (in c++) object orientation is something to strive for.

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?

Thank you very much in advance.
/ Alex
 
I

Ilkka Poutanen

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:

hello world

But in my opinion, this is very ugly. Especially if the class names

Are you sure you understand object-oriented programming? Reading the
Python tutorial[1] and re-reading the above error messages should clue
you in to what you're doing wrong. To put it simply, the whole point of
classes is that you create instances of them, each having their own
internal state, and then invoke their methods to accomplish whatever it
is that you want your program to accomplish.

1. http://docs.python.org/tut/
 
B

bruno at modulix

Alex said:
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:


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:


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:


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'

************************


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 !-) said:
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
 
D

Diez B. Roggisch

Some unbound method error. Have I missunderstood something or am I on
the right track here?

You misunderstood that you'd have to create an instance first before
invoking a method on that very instance. That is the same in C++, btw.
But in my opinion, this is very ugly. Especially if the class names
are long, like my module/class TileDataBaseManager. But is this the
"right" way in python?

I'm not sure what you mean by ugly. If you mean by ugly that you have to
instantiate an object before using it - that is the way it works in _all_
OO languages.

If you mean that you find it ugly to have long modulenames that are the same
as the class-name - yes it is ugly - but that is utterly your personal
decision to do so. In python, modules usually contain several classes, and
the module name groups them by function and has a name related to that
function. So most of the times one writes

import module

o = module.Class()

Which is not ugly - IMHO at least :) Especially not more ugly than using C++
namespaces, isn't it? And that is what a module essentially is: a
namespace.

Very clean from the outside. I would like something like this. But,
here, I loose the __init__ function. I have to call it manually that
is, which s not good. Also, maybe the biggest drawback, its no longer
in a class. Maybe its not that important in python but from what Ive
learned (in c++) object orientation is something to strive for.

You seem to have some troubles with OO in general and with the way python
does it. So I think it is kind of funny if you claim it is something to
strive for. OO is no silver bullet - if you have something that can be
dealt with using a function, it's perfectly good design to use one. Having
objects just for the sake of it introduces all sorts of problems, related
to unnecessary state, unclear implementation smeared over several methods
an the like.
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?

Group classes that belong to the same domain in one module. Import that,
possibly using an alias like

import MyLongDescriptiveModuleName as mn

don't fall for the temptation to use

from MyLongDescriptiveModuleName import *

as it will cause only more headache!

Diez
 
A

Alex

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'.




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.


Nope, it's just OO at work.


If you want to import a class from a module and create an instance of
that class, yes.


Which would be a sensible thing to do given the current implementation
of bar().


Nothing prevent you from putting many functions in a same module, you
know...


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').


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.


def MyFunc():
pass

print MyFunc.__class__.__name__

Python function's are instances of the function class.


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


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

Thanks for taking your time to help me out. :) You have cleared out
many of my doubts. BTW, should I post "thank you" stuff here or does
it just clutter? I tried sending an email to your personal email
listed (the one from which you send that mail to the list), but I got
this error:

PERM_FAILURE: DNS Error: Domain name not found

So I guess the entire list will have to be thanked for the help. :)
 
B

bruno at modulix

Alex said:
(snip)

Thanks for taking your time to help me out. :) You have cleared out
many of my doubts. BTW, should I post "thank you" stuff here

Ain't that what you just did ?-)
or does
it just clutter?

Nope, 'thank you' are always welcomes - eventually, take time to snip
irrelevant material (no use to repost 100+ lines just to add 'thank you'
at the bottom).
I tried sending an email to your personal email
listed (the one from which you send that mail to the list), but I got
this error:

PERM_FAILURE: DNS Error: Domain name not found

hint : have a look at my signature.
So I guess the entire list will have to be thanked for the help. :
)

indeed.
 

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,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top