Functional vs. Object oriented API

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Apr 12 00:20:36 EDT 2013


On Thu, 11 Apr 2013 00:16:19 +0100, Max Bucknell wrote:

> For example, I have a vector class, that works like so:
> 
>     >>> a = Vector([2, 7, 4])
>     >>> b = Vector.j # unit vector in 3D y direction
> 
> I also have a function to generate the dot product of these two vectors.
> In Java, such a function would be put as a method on the class and I
> would do something like:
> 
>     >>> a.dot_product(b)
>     7
> 
> and that would be the end of it. But in Python, I can also have:
> 
>     >>> dot_product(a, b)
>     7
> 
> Which of these two are preferred in Python? 

Both of them!

Python is a pure Object Oriented language in that all values are objects. 
(Unlike Java, where some values are unboxed primitives, and some are 
objects.) But Python does not force you to use Object Oriented syntax. 
You can where it makes sense. If not, you aren't forced to.


> And are there any general
> guidelines for choosing between the two styles, or is it largely a
> matter of personal preference?

I would put it like this:


- If you have a complicated interface, or data with complicated internal 
state, the best solution is to use a custom object with methods.


- But if your interface is simple, and the data is simple, it is more 
efficient to stick to lightweight built-ins. For example, a simple three-
tuple like (1, 4, 2) is probably more efficient than a Vector(1, 4, 2).
(Although there are ways to make classes more lean, and still give them 
methods.)


- If the *only* reason you use a class is to keep the data together, 
that's very much a Java design. In Python, you should put the functions 
in a module, and use that. E.g. if your class looks like this:

class MyClass:
    def __init__(self, data):
        self.data
    def spam(self):
        return spamify(self.data)
    def eggs(self, n):
        return eggify(self.data, n)
    def aardvark(self):
        return aardvarkify(self.data)


then using a class doesn't give you much, and you should expose spam, 
eggs and aardvark as top-level functions that take data as an argument.


You might like to watch this video from PyCon:

http://pyvideo.org/video/880/stop-writing-classes

or www.youtube.com/watch?v=o9pEzgHorH0

and then read this response:

http://lucumr.pocoo.org/2013/2/13/moar-classes/


Personally, I think that Armin Ronacher's response is important, but 
suffers from a fatal flaw. Monolithic code is Bad, agreed. But classes 
are not the only way to avoid monolithic code. Small, lightly coupled 
functions are just as good at breaking down monolithic code as classes. 
Some might even argue better.



-- 
Steven



More information about the Python-list mailing list