Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #92772 > unrolled thread

Classic OOP in Python

Started by"Jason P." <suscricions@gmail.com>
First post2015-06-17 12:21 -0700
Last post2015-06-18 21:43 +1000
Articles 10 on this page of 30 — 13 participants

Back to article view | Back to comp.lang.python


Contents

  Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-17 12:21 -0700
    Re: Classic OOP in Python Skip Montanaro <skip.montanaro@gmail.com> - 2015-06-17 14:38 -0500
    Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-17 12:44 -0700
      Re: Classic OOP in Python Marko Rauhamaa <marko@pacujo.net> - 2015-06-17 23:39 +0300
        Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-17 22:07 +0100
        Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-17 14:14 -0700
          Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-18 00:33 +0200
            Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-17 15:55 -0700
          Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-18 11:50 +0100
          Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-19 01:01 +0200
          Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-20 23:52 +0100
          Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-21 10:26 +0200
        Re: Classic OOP in Python sohcahtoa82@gmail.com - 2015-06-17 14:33 -0700
          Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-17 22:49 +0100
          Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-18 00:22 +0200
          Re: Classic OOP in Python Marco Buttu <marco.buttu@gmail.com> - 2015-06-18 11:00 +0200
        Re: Classic OOP in Python Laura Creighton <lac@openend.se> - 2015-06-18 00:09 +0200
        Re: Classic OOP in Python Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-17 23:27 +0100
        Re: Classic OOP in Python Steven D'Aprano <steve@pearwood.info> - 2015-06-18 08:58 +1000
          Re: Classic OOP in Python Cousin Stanley <cousinstanley@gmail.com> - 2015-06-18 08:10 -0700
        Re: Classic OOP in Python Terry Reedy <tjreedy@udel.edu> - 2015-06-17 19:46 -0400
        Re: Classic OOP in Python Chris Angelico <rosuav@gmail.com> - 2015-06-18 10:07 +1000
        Re: Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-18 04:24 -0700
      Re: Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-18 04:21 -0700
        Re: Classic OOP in Python Ned Batchelder <ned@nedbatchelder.com> - 2015-06-18 04:54 -0700
      Re: Classic OOP in Python "Jason P." <suscricions@gmail.com> - 2015-06-18 04:22 -0700
    Re: Classic OOP in Python sohcahtoa82@gmail.com - 2015-06-17 14:16 -0700
      Re: Classic OOP in Python Fabien <fabien.maussion@gmail.com> - 2015-06-18 13:03 +0200
        Re: Classic OOP in Python Marko Rauhamaa <marko@pacujo.net> - 2015-06-18 14:25 +0300
        Re: Classic OOP in Python Chris Angelico <rosuav@gmail.com> - 2015-06-18 21:43 +1000

Page 2 of 2 — ← Prev page 1 [2]


#92792

FromTerry Reedy <tjreedy@udel.edu>
Date2015-06-17 19:46 -0400
Message-ID<mailman.570.1434584839.13271.python-list@python.org>
In reply to#92777
On 6/17/2015 4:39 PM, Marko Rauhamaa wrote:
> Ned Batchelder <ned@nedbatchelder.com>:
>
>> TDD is about writing tests as a way to design the best system, and
>> putting testing at the center of your development workflow. It works
>> great with Python even without interfaces.

I use what I might call 'smart TDD'.  I think it a mistake to dismiss 
TDD because 'stupid TDD' is possible, and maybe even extant.

The reason for having a test initially fail is to make sure that the 
test is called.  A unittest example:

class NoTest(unittest.TestCase):
     def text_ohmygod(self):
         assertEqual(True, False)

Why does this 'pass'?  Within the last year, it was discovered that a 
TestCase subclass in one of the Python test files was not being run.  I 
made a similar mistake in my own code.  The more I do TDD 
(intelligently), the more I like it.

> I wonder how great it really is. Testing is important, that's for sure,
> but to make it a dogmatic starting point of development is not that
> convincing.

The bugs in Python, whether already fixed, on the tracker, or yet to be 
recorded, are the result of CPython not originally using TDD of some 
version.  In my opinion, CPython maintenance and enhancement has 
improved since some semblance of TDD was instituted.  A runable test is 
now the first stage for tracker issues.

> The way it was explained to me was that in TDD you actually don't write
> code to any requirements or design:

Writing sane code to pass tests based on requirements or a design is 
intended to ensure that one is actually meeting the design.

> you simply do the least to pass the tests.

The incantation I have read is 'simplest', not 'least'.  I personally 
interpret 'simplest' to include some presumption of sanity in relation 
to the ultimate goal.

 > Thus, say you need to write a program that inputs a string and
> outputs the same string surrounded by parentheses (the requirement),

One should write a reusable and easily testable *function* that takes a 
string as input (and outputs the same string surrounded by parens). 
Call the function paren_around.

 > the starting point might be this test case:
>
>     - run the program
>     - give it the word "hello" as input
>     - check that the program prints out "(hello)"

Doubly bad.

1. I consider mixing program i/o with function not related to i/o to be 
a bad idea.  TDD should cure one of this madness, not reinforce it.

2. The first test for smart TDD should best be with a falsey input (or 
other corner or edge case).  With this guideline, there is a good chance 
the 'simplest code' will be augmented rather than replaced with 
additional tests. A smart TDD test might be

     assertEqual(paren_arount(''), '()')

> The right TDD thing would be to satisfy the test with this program:
>
>     input()
>     print("(hello)")

This does not work.  The above adds '\n' to the end of the string, which 
is not part of the specification.  A human may not notice, but an 
automated test that captures stdout and compares with "(hello)" will 
notice and fail.

> That *ought* to be the first version of the program until further test
> cases are added that invalidate it.

As a statistician, I know about the mistake of overfitting functions to 
data.  'Teaching to the test' is a related mistake  Smart TDD should not 
reinforce bad practice.  This simple code passes the initial testcase above.

def paren_around(s):
     "Return string s surrounded by '(' and ')'."
     return '()'

Add a more generic (non-null) testcase.

     assertEqual(paren_around('abc', '(abc)')

The irrelevant details should usually be ignored when augmenting the 
code*.  The simplicity of this example makes it easy to write a correct 
assert, but is not relevant to the intent of the function.

def paren_around(s):
     "Return string s surrounded by '(' and ')'."
     return '({})'.format(s)

Code added, with nothing deleted.

> Another interesting ism I have read about is the idea that the starting
> point of any software project should be the user manual. The developers
> should then go and build the product that fits the manual.

The corresponding TDD approach is to write tests from the manual, and 
then write code.  One can also write tests from docs for existing code 
- and then see if the code passes the doc-based tests.  This is one way 
people discover bugs.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#92794

FromChris Angelico <rosuav@gmail.com>
Date2015-06-18 10:07 +1000
Message-ID<mailman.572.1434586050.13271.python-list@python.org>
In reply to#92777
On Thu, Jun 18, 2015 at 6:39 AM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Another interesting ism I have read about is the idea that the starting
> point of any software project should be the user manual. The developers
> should then go and build the product that fits the manual.

I've seldom met a *user* manual that's truly the right way to start
building, but there have been times when I've built *API*
documentation prior to the code. That can work fairly well. I'll also
often start a project with a copious set of notes that aren't quite
user-facing, aren't quite programmer-friendly, but are somewhere in
between. Here's a new project I'm starting now:

https://github.com/Rosuav/ThirdSquare

Prior to actually creating that repo, I'd done some thrash testing of
the basic concepts (which is how I know that the basic idea will work
- my thrash test achieved 100tps, massively exceeding the 40tps that I
need, ergo it's worth proceeding to code), but the project itself
started with the README, then the .sql files giving a basic run-down
of the tables required. Now, and only now, I'm starting to look at
actual code. Is that starting with the user manual? Not quite, but I
think it captures the same concept that that's trying to capture.

ChrisA

[toc] | [prev] | [next] | [standalone]


#92820

From"Jason P." <suscricions@gmail.com>
Date2015-06-18 04:24 -0700
Message-ID<42563233-5269-41e7-87a9-1bde66480d09@googlegroups.com>
In reply to#92777
El miércoles, 17 de junio de 2015, 22:39:31 (UTC+2), Marko Rauhamaa  escribió:
> Ned Batchelder <ned@nedbatchelder.com>:
> 
> > TDD is about writing tests as a way to design the best system, and
> > putting testing at the center of your development workflow. It works
> > great with Python even without interfaces.
> 
> I wonder how great it really is. Testing is important, that's for sure,
> but to make it a dogmatic starting point of development is not that
> convincing.
> 
> The way it was explained to me was that in TDD you actually don't write
> code to any requirements or design: you simply do the least to pass the
> tests. Thus, say you need to write a program that inputs a string and
> outputs the same string surrounded by parentheses (the requirement), the
> starting point might be this test case:
> 
>    - run the program
>    - give it the word "hello" as input
>    - check that the program prints out "(hello)"
> 
> The right TDD thing would be to satisfy the test with this program:
> 
>    input()
>    print("(hello)")
> 
> That *ought* to be the first version of the program until further test
> cases are added that invalidate it.
> 
> 
> Another interesting ism I have read about is the idea that the starting
> point of any software project should be the user manual. The developers
> should then go and build the product that fits the manual.
> 
> 
> Marko

The refactor phase is key in TDD (red-green-refactor). Again, GOOS is an advisable source of knowledge in this matter.

[toc] | [prev] | [next] | [standalone]


#92818

From"Jason P." <suscricions@gmail.com>
Date2015-06-18 04:21 -0700
Message-ID<01adfef5-7edf-447c-9397-853c4fd65e53@googlegroups.com>
In reply to#92775
El miércoles, 17 de junio de 2015, 21:44:51 (UTC+2), Ned Batchelder  escribió:
> On Wednesday, June 17, 2015 at 3:21:32 PM UTC-4, Jason P. wrote:
> > Hello Python community.
> > 
> > I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on.
> > 
> > Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP?
> > 
> > For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python?
> > 
> > 
> > Many thanks!
> 
> What other languages do with interfaces, Python does with duck-typing. You
> can build something like interfaces in Python, but many people don't bother.
> 
> I don't know if your project will be web-based, but here is an entire book
> about developing Python web sites with a TDD approach:
> 
> http://www.obeythetestinggoat.com/
> 
> (Don't mind the unusual domain name, it's a bit of an inside joke...)
> 
> TDD and interfaces are separate concepts, and I'm not sure they even
> intersect.  TDD is about writing tests as a way to design the best system,
> and putting testing at the center of your development workflow.  It works
> great with Python even without interfaces.
> 
> --Ned.

I'm aware of duck typing. The point in using interfaces is to be explicit about the boundaries of a system.

Quite a red "Growing Object-Oriented Software, Guided by Tests", by the way. In fact interfaces are key components in the style of building software they propose, in good company with TDD.

Thx!

[toc] | [prev] | [next] | [standalone]


#92823

FromNed Batchelder <ned@nedbatchelder.com>
Date2015-06-18 04:54 -0700
Message-ID<69585e5b-a8c6-413b-849b-ce51585b72c7@googlegroups.com>
In reply to#92818
On Thursday, June 18, 2015 at 7:21:29 AM UTC-4, Jason P. wrote:
> El miércoles, 17 de junio de 2015, 21:44:51 (UTC+2), Ned Batchelder  escribió:
> > On Wednesday, June 17, 2015 at 3:21:32 PM UTC-4, Jason P. wrote:
> > > Hello Python community.
> > > 
> > > I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on.
> > > 
> > > Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP?
> > > 
> > > For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python?
> > > 
> > > 
> > > Many thanks!
> > 
> > What other languages do with interfaces, Python does with duck-typing. You
> > can build something like interfaces in Python, but many people don't bother.
> > 
> > I don't know if your project will be web-based, but here is an entire book
> > about developing Python web sites with a TDD approach:
> > 
> > http://www.obeythetestinggoat.com/
> > 
> > (Don't mind the unusual domain name, it's a bit of an inside joke...)
> > 
> > TDD and interfaces are separate concepts, and I'm not sure they even
> > intersect.  TDD is about writing tests as a way to design the best system,
> > and putting testing at the center of your development workflow.  It works
> > great with Python even without interfaces.
> > 
> > --Ned.
> 
> I'm aware of duck typing. The point in using interfaces is to be explicit about the boundaries of a system.
> 
> Quite a red "Growing Object-Oriented Software, Guided by Tests", by the way. In fact interfaces are key components in the style of building software they propose, in good company with TDD.

Yes, that book uses interfaces, because that book uses Java.  Different
languages offer different tools.  You can make interfaces in Python, but you
don't need to.  They aren't enforced by Python, so you aren't gaining much
other than documentation from them, so why not just use documentation?

Abstract classes provide another tool.  They can insist that you provide
implementations of abstract methods.  In my experience, it is easy to get
to a point where you are struggling to satisfy your simple-minded abstract
classes, rather than writing the code that you know you need to solve your
actual problem.  As Chris just mentioned elsewhere in this thread, you have
to be very careful how you define your abstract classes.  I've worked in 
Java projects where I had to provide 10 dummy implementations of methods I
knew I wasn't going to need, just because the interface insisted they had
to exist.

The Python culture is to document your expectations, and write enough tests
to verify that your code does what it claims to do.  You are already planning
on a TDD flow, so you will have plenty of tests.

Try doing without interfaces or abstract classes.  See how it goes. It's the
Python way. :)

--Ned.

[toc] | [prev] | [next] | [standalone]


#92819

From"Jason P." <suscricions@gmail.com>
Date2015-06-18 04:22 -0700
Message-ID<48b428f0-7373-4847-b1fd-2c8532c056ee@googlegroups.com>
In reply to#92775
El miércoles, 17 de junio de 2015, 21:44:51 (UTC+2), Ned Batchelder  escribió:
> On Wednesday, June 17, 2015 at 3:21:32 PM UTC-4, Jason P. wrote:
> > Hello Python community.
> > 
> > I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on.
> > 
> > Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP?
> > 
> > For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python?
> > 
> > 
> > Many thanks!
> 
> What other languages do with interfaces, Python does with duck-typing. You
> can build something like interfaces in Python, but many people don't bother.
> 
> I don't know if your project will be web-based, but here is an entire book
> about developing Python web sites with a TDD approach:
> 
> http://www.obeythetestinggoat.com/
> 
> (Don't mind the unusual domain name, it's a bit of an inside joke...)
> 
> TDD and interfaces are separate concepts, and I'm not sure they even
> intersect.  TDD is about writing tests as a way to design the best system,
> and putting testing at the center of your development workflow.  It works
> great with Python even without interfaces.
> 
> --Ned.

I forgot to mention that the book you recommend seems to be a good starting point ;)

[toc] | [prev] | [next] | [standalone]


#92781

Fromsohcahtoa82@gmail.com
Date2015-06-17 14:16 -0700
Message-ID<f0c76343-7230-499c-ba30-33d7f6513503@googlegroups.com>
In reply to#92772
On Wednesday, June 17, 2015 at 12:21:32 PM UTC-7, Jason P. wrote:
> Hello Python community.
> 
> I come from a classic background in what refers to OOP. Mostly Java and PHP (> 5.3). I'm used to abstract classes, interfaces, access modifiers and so on.
> 
> Don't get me wrong. I know that despite the differences Python is fully object oriented. My point is, do you know any book or resource that explains in deep the pythonic way of doing OOP?
> 
> For example, I'm gonna try to develop a modest application from ground up using TDD. If it had been done in Java for instance, I would made extensive use of interfaces to define the boundaries of my system. How would I do something like that in Python?
> 
> 
> Many thanks!

You don't need interfaces with Python.  Duck typing makes that all possible.  This is perfectly valid:

class Dog(object):
    def move(self):
        print "Dog is moving"

class Car(object):
    def move(self):
        print "Car is moving"

things = [Dog(), Car()]
for thing in things:
    thing.move()

Despite Dog and Car being completely different classes with no relationship with each other, the code runs just fine.

[toc] | [prev] | [next] | [standalone]


#92816

FromFabien <fabien.maussion@gmail.com>
Date2015-06-18 13:03 +0200
Message-ID<mlu8hh$ntr$1@speranza.aioe.org>
In reply to#92781
On 06/17/2015 11:16 PM, sohcahtoa82@gmail.com wrote:
> You don't need interfaces with Python.  Duck typing makes that all possible.

Yes, but I also like interfaces (or in python: mimicked interfaces with 
NotImplementedError) for their clarity and documentation purposes.

Would you consider the following kind of program "unpythonic"?

class MovingObject(object):
     """Great doc about what a moving object is"""

     def move(self):
     	"""Great doc about move"""
         raise NotImplementedError()

class Dog(MovingObject):
     def move(self):
         print "Dog is moving"

class Car(MovingObject):
     def move(self):
         print "Car is moving"

(Disclaimer: I learned OOP with Java)

Fabien

[toc] | [prev] | [next] | [standalone]


#92821

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-06-18 14:25 +0300
Message-ID<87oakdz2ah.fsf@elektro.pacujo.net>
In reply to#92816
Todd <toddrjen@gmail.com>:

> On Thu, Jun 18, 2015 at 1:03 PM, Fabien <fabien.maussion@gmail.com> wrote:
>> Would you consider the following kind of program "unpythonic"?
>>
>> class MovingObject(object):
>>     """Great doc about what a moving object is"""
>>
>>     def move(self):
>>         """Great doc about move"""
>>         raise NotImplementedError()
>>
>> class Dog(MovingObject):
>>     def move(self):
>>         print "Dog is moving"
>>
>> class Car(MovingObject):
>>     def move(self):
>>         print "Car is moving"
>>
>> (Disclaimer: I learned OOP with Java)
>>
>>
> I think this is what abstract base classes are for in Python.

And they can be ok as long as you're not making them into a habit.


Marko

[toc] | [prev] | [next] | [standalone]


#92822

FromChris Angelico <rosuav@gmail.com>
Date2015-06-18 21:43 +1000
Message-ID<mailman.595.1434627811.13271.python-list@python.org>
In reply to#92816
On Thu, Jun 18, 2015 at 9:03 PM, Fabien <fabien.maussion@gmail.com> wrote:
> Would you consider the following kind of program "unpythonic"?
>
> class MovingObject(object):
>     """Great doc about what a moving object is"""
>
>     def move(self):
>         """Great doc about move"""
>         raise NotImplementedError()
>
> class Dog(MovingObject):
>     def move(self):
>         print "Dog is moving"
>
> class Car(MovingObject):
>     def move(self):
>         print "Car is moving"
>
> (Disclaimer: I learned OOP with Java)

Now try extending the concept to two, three, or four such interfaces.
Files can be moved, opened, copied, and unlinked. Should they share
any sort of interface with dogs, boxes, handwriting, and railway
carriages? It's much better to simply define the attributes of each
object separately; most non-trivial cases don't involve simple methods
with no additional arguments, and the chances of an incompatibility
(or worse, a forced compatibility) go up.

ChrisA

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web