tags:

views:

146

answers:

5

I've seen some people writing Python code by creating one class and then an object to call all the methods. Is there any advantage of using classes if we don't make use of inheritance, encapsulation etc? Such code seems to me less clean with all these 'self' arguments, which we could avoid. Is this practice an influence from other programming languages such as Java or is there any good reason why Python programs should be structured like this?

example code:

class App:

# all the methods go here

a = App()    
+5  A: 

One advantage, though not always applicable, is that it makes it easy to extend the program by subclassing the one class. For example I can subclass it and override the method that reads from, say, a csv file to reading an xml file and then instantiate the subclass or original class based on run-time information. From there, the logic of the program can proceed normally.

That of course raises the question of if reading the file is really the responsibility of the class or more properly belongs to a class that has subclasses for reading different types of data and presents a uniform interface to that data but that is, of course, another question.

Personally, I find that the cleanest way to do it is to put functions which make strong assumptions about their parameters on the appropriate class as methods and to put functions which make very weak assumptions about their arguments in the module as functions.

aaronasterling
+1. I like to package my apps as subclassable application objects, so they can be customised by a subclass and different customised versions run in parallel (which wouldn't be possible with monkey-patching). This tends to involve lots of inner classes, also subclassable, for more complicated apps.
bobince
That makes perfect sense. Thanks aaronasterling and bobince!
Thea
+3  A: 

I often do the same myself for the managers parts of an app which, in theory, could be reduced to simple, very sequential, functional programming.

The main advantage to it (for me) is that it encapsulates well your main loop or your run-once execution, and it allows to configure that run and persist data efficiently and cleanly across blocks, fundamentally re-configuring it as needed without having to change the code itself. Not to mention the ability to subclass an execution to a different and extended one.

It also tends to be a lot easier to expand the main that way, then it is when you have a solid block of 200 lines throwing around rather cryptically scoped stuff.

The self, after you write enough Python, kinda goes away as an impedement, and personally I like how it immediately offers a visual distinction between what I will obviously want to persist across scopes, and what is a disposable element that I DO want to run out of scope and get collected as soon as a particular step is done.

Last but not least, some people will object orient anything they get their hands on, or won't be able to read it. I'm one of them :)

ThE_JacO
Well, you can always use a main function for your 'run-once execution' but if you want to extend the program in the future it does make sense to have an object-oriented design. Thanks for your answer :)
Thea
+2  A: 

1. I know of one use for this.

Though this can be achieved by other means. It ensures that both modules - module_B and module_C uses the same instance of App and do not instantiate separate objects.

In module_A.py

class App:
   ....

a = App()

In module_B.py

from module_A import a

In module_C.py

from module_A import a

Of course, you could create separate objects but that was is not the intention of above modules.

What if you did the following in module_D.py

from module_A import App
a = App()

2. [Pedantic]

You could avoid using classes and decompose your solution using only modules and functions. But won't that look ugly in a large program. Wouldn't you want to use object oriented paradigm in your program. All languages provide certain way to take advantage of OO. We all like some thing or the other and some do turn us off. Explicit is better than implicit is usually the Python way. Though this is not good enough reason for it's inclusion.

pyfunc
Thanks a lot! Very very helpful :)
Thea
A: 

Is there any advantage of using classes if we don't make use of inheritance, encapsulation etc?

Yes.

this practice an influence from other programming languages such as Java

No.

There any good reason why Python programs should be structured like this?

Yes.

However. From your question, you've clearly decided that "Such code seems to me less clean with all these 'self' arguments".

There's not a lot of point in explaining the advantages of a class declaration if you're already sure it's "less clean".

Consider this.

  1. A script is never static.
  2. A class-free design will have to be changed.
  3. At some point, the changes will lead to a second class.

Bottom-line.

You can work without a class for brief moments. Until you make changes. Then you'll regret not having the word class and all those "unclean" self arguments.

You'll add them eventually.

Why wait?

S.Lott
+1  A: 

I tend to use classes when I think it is likely that I will need multiple instances of something, or if I think inheriting from it will be useful. If I'm just looking for a way to group related functions and settings that affect their behavior, well, a module can work just as well for that, with less syntax. Sometimes I will use both approaches in the same module.

Also, although you can write decorators and context managers as classes, I personally tend to find them clearer when written as functions, so that's how I typically write them.

Python is a multi-paradigm programming language. Use whatever approach you feel expresses your intent most clearly. You never need to use OO.

An approach I like to use is to think of how I'd want the various pieces of functionality provided to me if someone else was going to write a module to solve a problem like mine in a generic way. Basically, I try to design the interfaces between my modules first, and make each as simple and easy to use as possible. At this point, it starts to become clear to me what approach I should use for each bit of functionality.

But I'm just one guy, and programming is not my main job.

kindall
I've always thought context managers as functions look weird and crufty. I'm with you in thinking then when its possible to use a function as a decorator, it's the right thing to do in most cases.
aaronasterling
To each his own, and of course my opinions are subject to change as I learn more about Python. The thing I like about context managers as functions is that you don't have to use instance variables if you want to share state between your `__enter__()` and `__exit()__`. Just plain old locals work fine.
kindall