Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #43301 > unrolled thread
| Started by | Max Bucknell <mpwb500@york.ac.uk> |
|---|---|
| First post | 2013-04-11 00:16 +0100 |
| Last post | 2013-04-13 09:51 +0100 |
| Articles | 8 — 7 participants |
Back to article view | Back to comp.lang.python
Functional vs. Object oriented API Max Bucknell <mpwb500@york.ac.uk> - 2013-04-11 00:16 +0100
Re: Functional vs. Object oriented API Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-04-12 04:20 +0000
Re: Functional vs. Object oriented API Roy Smith <roy@panix.com> - 2013-04-12 10:19 -0400
Re: Functional vs. Object oriented API Mitya Sirenef <msirenef@lightbird.net> - 2013-04-12 10:29 -0400
Re: Functional vs. Object oriented API David M Chess <chess@us.ibm.com> - 2013-04-12 11:37 -0400
Re: Functional vs. Object oriented API 88888 Dihedral <dihedral88888@googlemail.com> - 2013-04-12 22:25 -0700
Re: Functional vs. Object oriented API 88888 Dihedral <dihedral88888@googlemail.com> - 2013-04-12 22:25 -0700
Re: Functional vs. Object oriented API Rui Maciel <rui.maciel@gmail.com> - 2013-04-13 09:51 +0100
| From | Max Bucknell <mpwb500@york.ac.uk> |
|---|---|
| Date | 2013-04-11 00:16 +0100 |
| Subject | Functional vs. Object oriented API |
| Message-ID | <mailman.429.1365635789.3114.python-list@python.org> |
Hi,
I'm currently learning Python, and it's going great. I've dabbled before, but really getting into it is good fun.
To test myself, and not detract too much from my actual studies (mathematics), I've been writing my own package to do linear algebra, and I am unsure about how best to structure my API.
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? And are there any general guidelines for choosing between the two styles, or is it largely a matter of personal preference?
Thanks for reading,
Max.
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-04-12 04:20 +0000 |
| Message-ID | <51678b94$0$29977$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #43301 |
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
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2013-04-12 10:19 -0400 |
| Message-ID | <roy-E3B2B9.10194712042013@news.panix.com> |
| In reply to | #43417 |
In article <51678b94$0$29977$c3e8da3$5496439d@news.astraweb.com>, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > - 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 [...] > > - If the *only* reason you use a class is to keep the data together, > that's very much a Java design. As part of our initial interview screen, we give applicants some small coding problems to do. One of the things we see a lot is what you could call "Java code smell". This is our clue that the person is really a Java hacker at heart who just dabbles in Python but isn't really fluent. It's kind of like how I can walk into a Spanish restaurant and order dinner or enquire where the men's room is, but everybody knows I'm a gringo as soon as I open my mouth. It's not just LongVerboseFunctionNamesInCamelCase(). Nor is it code that looks like somebody bought the Gang of Four patterns book and is trying to get their money's worth out of the investment. The real dead giveaway is when they write classes which contain a single static method and nothing else. That being said, I've noticed in my own coding, it's far more often that I start out writing some functions and later regret not having initially made it a class, than the other way around. That's as true in my C++ code as it is in my Python. In my mind, classes are all about data. If there's no data (i.e. no stored state), you should be thinking a collection of functions. On the other hand, if there's ONLY data and no behavior, then you should be thinking namedtuple (which is really just a shortcut way to write a trivial class). Once you start having state (i.e. data) and behavior (i.e. functions) in the same thought, then you need a class. If you find yourself passing the same bunch of variables around to multiple functions, that's a hint that maybe there's a class struggling to be written.
[toc] | [prev] | [next] | [standalone]
| From | Mitya Sirenef <msirenef@lightbird.net> |
|---|---|
| Date | 2013-04-12 10:29 -0400 |
| Message-ID | <mailman.522.1365776990.3114.python-list@python.org> |
| In reply to | #43452 |
On 04/12/2013 10:19 AM, Roy Smith wrote: > As part of our initial interview screen, we give applicants some small > coding problems to do. One of the things we see a lot is what you could > call "Java code smell". This is our clue that the person is really a > Java hacker at heart who just dabbles in Python but isn't really fluent. > It's kind of like how I can walk into a Spanish restaurant and order > dinner or enquire where the men's room is, but everybody knows I'm a > gringo as soon as I open my mouth. > > It's not just LongVerboseFunctionNamesInCamelCase(). Nor is it code > that looks like somebody bought the Gang of Four patterns book and is > trying to get their money's worth out of the investment. The real dead > giveaway is when they write classes which contain a single static method > and nothing else. > > That being said, I've noticed in my own coding, it's far more often that > I start out writing some functions and later regret not having initially > made it a class, than the other way around. I've absolutely noticed the same thing for myself, over and over again. I can't remember writing a class that I've regretted is not a few functions, although it must have happened a few times. -m -- Lark's Tongue Guide to Python: http://lightbird.net/larks/
[toc] | [prev] | [next] | [standalone]
| From | David M Chess <chess@us.ibm.com> |
|---|---|
| Date | 2013-04-12 11:37 -0400 |
| Message-ID | <mailman.527.1365781666.3114.python-list@python.org> |
| In reply to | #43452 |
[Multipart message — attachments visible in raw view] — view raw
> Roy Smith <roy@panix.com> > As part of our initial interview screen, we give applicants some small > coding problems to do. One of the things we see a lot is what you could > call "Java code smell". This is our clue that the person is really a > Java hacker at heart who just dabbles in Python but isn't really fluent. > ... > It's not just LongVerboseFunctionNamesInCamelCase(). Nor is it code > that looks like somebody bought the Gang of Four patterns book and is > trying to get their money's worth out of the investment. The real dead > giveaway is when they write classes which contain a single static method > and nothing else. I may have some lingering Java smell myself, although I've been working mostly in Python lately, but my reaction here is that's really I don't know "BASIC smell" or something; a class that contains a single static method and nothing else isn't wonderful Java design style either. > That being said, I've noticed in my own coding, it's far more often that > I start out writing some functions and later regret not having initially > made it a class, than the other way around. That's as true in my C++ > code as it is in my Python. Definitely. > Once you start having state (i.e. data) and behavior (i.e. functions) in > the same thought, then you need a class. If you find yourself passing > the same bunch of variables around to multiple functions, that's a hint > that maybe there's a class struggling to be written. And I think equally to the point, even if you have only data, or only functions, right now, if the thing in question has that thing-like feel to it :) you will probably find yourself with both before you're done, so you might as well make it a class now... DC
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2013-04-12 22:25 -0700 |
| Message-ID | <f22e42d0-1ac7-412f-b1a7-e8325288fdaf@googlegroups.com> |
| In reply to | #43465 |
David M Chess於 2013年4月12日星期五UTC+8下午11時37分28秒寫道: > > Roy Smith <r...@panix.com> > > > > > > As part of our initial interview screen, we give > applicants some small > > > coding problems to do. One of the things we see a lot is what > you could > > > call "Java code smell". This is our clue that the > person is really a > > > Java hacker at heart who just dabbles in Python but isn't really fluent. > > > > ... > > > It's not just LongVerboseFunctionNamesInCamelCase(). Nor is > it code > > > that looks like somebody bought the Gang of Four patterns book and > is > > > that maybe there's a class struggling to be written. > > > > And I think equally to the point, even if you have > only data, or only functions, right now, if the thing in question has that > thing-like feel to it :) you will probably find yourself with both before > you're done, so you might as well make it a class now... > > > > DC If it is not time-critical and no needs to convert into CYTHON then it does not matter too much. But a well wrapped class structures with good documents can help others to use the python codes a lot. If the part is intended to be time-critical in the low level part, then avoiding seeking 4 levels of methods and properties inside a loop is helpful in python programs to be executed in the run time.
[toc] | [prev] | [next] | [standalone]
| From | 88888 Dihedral <dihedral88888@googlemail.com> |
|---|---|
| Date | 2013-04-12 22:25 -0700 |
| Message-ID | <mailman.546.1365830740.3114.python-list@python.org> |
| In reply to | #43465 |
David M Chess於 2013年4月12日星期五UTC+8下午11時37分28秒寫道: > > Roy Smith <r...@panix.com> > > > > > > As part of our initial interview screen, we give > applicants some small > > > coding problems to do. One of the things we see a lot is what > you could > > > call "Java code smell". This is our clue that the > person is really a > > > Java hacker at heart who just dabbles in Python but isn't really fluent. > > > > ... > > > It's not just LongVerboseFunctionNamesInCamelCase(). Nor is > it code > > > that looks like somebody bought the Gang of Four patterns book and > is > > > that maybe there's a class struggling to be written. > > > > And I think equally to the point, even if you have > only data, or only functions, right now, if the thing in question has that > thing-like feel to it :) you will probably find yourself with both before > you're done, so you might as well make it a class now... > > > > DC If it is not time-critical and no needs to convert into CYTHON then it does not matter too much. But a well wrapped class structures with good documents can help others to use the python codes a lot. If the part is intended to be time-critical in the low level part, then avoiding seeking 4 levels of methods and properties inside a loop is helpful in python programs to be executed in the run time.
[toc] | [prev] | [next] | [standalone]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2013-04-13 09:51 +0100 |
| Message-ID | <kkb65c$66o$1@dont-email.me> |
| In reply to | #43301 |
Max Bucknell wrote: > Hi, > I'm currently learning Python, and it's going great. I've dabbled before, > but really getting into it is good fun. > > To test myself, and not detract too much from my actual studies > (mathematics), I've been writing my own package to do linear algebra, and > I am unsure about how best to structure my API. > > 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 Not necessarily. That would only happen if that code was designed that way. It's quite possible, and desirable, that the dot product isn't implemented as a member function of the vector data type, and instead is implemented as an operator to be applied to two object. > 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? And are there any general > guidelines for choosing between the two styles, or is it largely a matter > of personal preference? The separation of concerns principle is a good guideline. This doesn't apply exclusively to Python; it essentiallyl applies to all programming languages. http://en.wikipedia.org/wiki/Separation_of_concerns There are significant advantages in separating the definition of a data type from the definition of the operations that are to be applied to it. If operations are decoupled from the data type then it's possible to preserve the definition of that data type eternally, while the operators that are written to operate on it can be added, tweaked and removed independently and at anyone's whims. Hope this helps, Rui Maciel
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web