[newbie] Looking for a good introduction to object orientedprogramming with Python

A

alex23

In my not-so-humble opinion, the popularity of Design Patterns has a lot
to do with the fact that they are so abstract and jargon-ridden that they
have become a badge of membership into an elite. Shorn of their excessive
abstractness, they're not very special. People were writing helper
functions to assemble complex data long before the Builder pattern was
named, and a Facade is just an interface layer.

I think you've entirely missed the point of Design Patterns.

No one claims that the Go4 DP book introduced Builders, Singletons,
Facades. The point was to identify _and name_ such patterns, so
programmers could actually talk about repeated behaviour. Design
patterns are an attempt to encapsulate and express experience, that's
it. There's nothing mystical or special about them at all, and to be
honest I never ever such claims come from proponents of them, only
their critics.

Why is it an "elitist" action to want to be able to share experience
and learn from that of others? If anything, I find the problem is with
the insular nature of most developers and the preponderance of NIH
attitudes.
 
S

Steven D'Aprano

While I've probably used singletons (usually as sentinels in queues,

I don't know your code, but if I were to take a wild guess, I would say
that apart from None, and True/False, you probably haven't.

NotImplemented and Ellipsis are two other singletons in Python. It is
possible to program a Singleton class in pure Python, but most people
don't bother, because 1) singleton is probably the most over-used Design
Pattern of them all and 2) it's quite trivial to bypass the singleton-ness
of classes written in Python and create a second instance.

Or they use a module, which is not really a singleton but behaves like
one. Or if they want to show off their Pythonicity, they use the Borg
pattern.

The common sentinel idiom in Python is to do this:

SENTINEL = object()
# and later...
if value is SENTINEL:
pass


but of course that's not a singleton because it's only one instance out
of a vast number, and anyone can create another instance. Also it misses
the point of the Singleton pattern, that the (lone) instance should hold
state. The sentinel does not usually hold state.


I suspect), but can't say that I've ever used a "factory function"...

If you've ever used an ordinary function decorator, you almost certainly
have.

If you've every created a closure, you definitely have.
 
W

Wolfgang Strobl

Dennis Lee Bieber said:
Don't look for Object-Oriented Programming -- since the first widely
popular OOP language was C++ (Smalltalk was earlier, but rather
specialized, whereas C++ started as a preprocessor for C).

Well, C++ did to C what Simula 67 did to Algol 60, much earlier. Simula
was quite popular at its time.

<http://en.wikipedia.org/wiki/Simula>
 
P

Paul Rubin

Steven D'Aprano said:
If you've ever used an ordinary function decorator, you almost certainly
have.
If you've every created a closure, you definitely have.

Or anything with a __iter__ method...
 
D

DJC

I frequently draw diagrams to understand the relationships between my
classes and the problem I am trying to solve. I almost invariably use one
type of box and one type of arrowhead. Sometimes if I'm bored I draw
doodles on the diagram. If only I could remember to be consistent about
what doodle I draw where, I too could be an UML guru.
Flow Charts redux
 
R

rusi

Object Oriented programming is a mindset, a way of looking at that
particular part of our world that you are trying to encapsulate
in computer language. The language you use is (should be) irrelevant.

Actually it should really be called Class Oriented programming as
classes are the units of encapsulation.
I really don't think python is a good language to learn OO programming,
the problem is that Python doesn't enforce OO so you are never going to
learn what is 'OO' and what isn't.
Learn Python by all means, the interactive mode is particularly fun,just
try and get a good idea of what OO is all about before you start.

I suggest this
http://steve-yegge.blogspot.in/2006/03/execution-in-kingdom-of-nouns.html

Particularly useful if you are a bit drunk on snake-oil
 
R

Roy Smith

lipska the kat said:
UML works, non technical 'stakeholders' (yuk) can understand it at a
high level and in my HUMBLE opinion the sequence diagram is the single
most important piece of documentation in the entire software project

Yup. Sequence diagrams are the most common one I draw. I'm sure I use
the wrong kinds of arrowheads and such, but the general idea is pretty
powerful.

I find they can be useful for figuring out some horrible piece of code
you've never worked with before. Just sit down and start reading the
code, drawing the diagram as you go. Sometimes things start to make
sense that way when just staring at the code isn't doing it for you.

My most successful experiment with UML was when trying to understand
some big hunk of C++ somebody had thrown at me. I imported the whole
thing into some UML tool, which not only found all the classes, but also
sorted out how they were related. Pushing boxes around in the GUI tool
turned out to be a useful way to get my head around how the code worked.

The problem with UML is that, like so many good ideas, it has developed
a mystique around it. With layers of gurus who know progressively more
and more about the esoteric details. And who make a living writing
books and giving seminars about it. Kind of like patterns, and agile,
and scrum, and XP, and so on.
 
J

Jean Dubois

Thanks, this one is a lot better. Could you just tell me what the use
is of the following lines:
"""Class docstring."""
"""Method docstring."""
"""Method docstring."""
Taken from the following code fragment (I really want to understand
every bit of code, and the author doesn't mention this)


class OurClass(object):
"""Class docstring."""

def __init__(self, arg1, arg2):
"""Method docstring."""
self.arg1 = arg1
self.arg2 = arg2

def printargs(self):
"""Method docstring."""
print self.arg1
print self.arg2



thanks in advance
jean
 
M

Mark Lawrence

Please see my comment at the bottom hint hint :)

Its a docstring - it documents the function/class
Did you know that docstrings can be used for testing - look at the doctest
standard library module!
try:

class A:
def method(self):
'''Sample method
This method does the difficult task X.
Call this method with no arguments.'''#docstring
pass

then type :

help(A.method)

And viola!
(C++/Java) object-orientation is not a be all and end all in Python, in
fact you could work with Python for a long time without really 'doing it'
at all (well other than calling methods/properties on existing API's).
Having said that here's what I would suggest ...
but you could bookmark it for the future:
Thanks, this one is a lot better. Could you just tell me what the use
is of the following lines:
"""Class docstring."""
"""Method docstring."""
"""Method docstring."""
Taken from the following code fragment (I really want to understand
every bit of code, and the author doesn't mention this)


class OurClass(object):
"""Class docstring."""

def __init__(self, arg1, arg2):
"""Method docstring."""
self.arg1 = arg1
self.arg2 = arg2

def printargs(self):
"""Method docstring."""
print self.arg1
print self.arg2



thanks in advance
jean

Ramchandra Apte will you please stop top posting. In your native
language you may well but from bottom to top, but this news group
prefers reading top to bottom :) Thanks.
 
C

Chris Angelico

BTW in "automatic garbage collection" which of the three words is most
important? Least?

Most important is "garbage". I sure don't want any language I use to
automatically collect non-garbage!!

But in seriousness, the definition of "garbage" is one of the trickier
things to work out, hence the variety of schemes (mark/sweep,
refcount, various forms of cycle detection, etc).

ChrisA
 
S

Steven D'Aprano

Please see my comment at the bottom hint hint :)

Please trim unnecessary quoted text.

We don't need to see the entire thread of comment/reply/reply-to-reply
duplicated in *every* email.
 
S

Steven D'Aprano

The clue is in the name 'Object Oriented' ... anything else is (or
should be) implementation detail.

So your argument is that any programming which is "oriented" (meaning
what?) towards "objects" (which are...?) is OOP, and everything else is
"implementation detail".

Well now I'm enlightened. That certainly clears that up for me.

[large snip]

In particularly, terminology varies -- I personally despise with the
heat of a thousand suns the terms "instance variable" and "class
variable" for attributes or members.

This is an implementation detail and describes the difference between
certain types of attributes.

Not everything is an "implementation detail". The difference between a so-
called "class variable" (what Python calls a class attribute) and a
"instance variable" (instance attribute) is not an implementation detail,
it is a difference in semantics and function.


As you go on to explain:
A class variable is static and can be
accessed without instantiation an instance variable is accessed via an
instance

which are semantic differences, differences in meaning and function.

Class variable and instance variable are higher level abstractions.

Of what? Of variables? "Class variables are an abstraction of
variables"... even if true, that's a crappy way to speak. Why should you
use the same word for higher level abstractions that is already used for
lower level abstractions?

I understand that in Java, classes are not first-class (no pun intended)
objects. You can't say:

x = MyClass

and hence talk about x being a variable that holds a class, hence "class
variable". But that's no excuse to overload the term "variable" for
something where there are at least three good names:

attribute
member
property

none of which clash with the normal use of the word "variable".

(Smalltalk gets a pass here -- it was very early days in OOP, and the
terminology wasn't available. But by the time that Java came along, there
was no longer any good justification for overloading a perfectly good
word like variable to mean something different.)

Simply put, the choice of terminology is crap -- attributes of a class/
instance have subtle but real semantic differences from local/global
variables. Attributes belong to an entity (an instance, or a class);
variables do not.

If they were just implementation differences ("local variables live on
the stack, attributes live in the instance struct") it wouldn't matter.
But the semantics are different, and the "instance variable" terminology
is misleading.

But what *really* gets me is not the existence of poor terminology. I
couldn't care less what terminology Java programmers use among
themselves. What gets me is that the ubiquity of them means that
substandard terminology spreads into other languages, like dryrot.

You have answered your own question....

I'm afraid I have no idea what you mean here. Do you mean that you
*don't* have any non-religious reasons for avoiding Person and User
objects?

How do you feel about Person and User structs, records or fields?

I would be glad to debate my
assertion at length with you however the 'moderators' are listening.

There are no moderators on this list. People are free to try using peer
pressure to discourage off-topic discussion, but they can't enforce it.


A problem? I wasn't aware that I'd stated it was a problem it just

You said "BUT [emphasis added] I haven't invented a single class yet",
which implies that this is a bad thing in contrast to the good thing that
you became productive in Python very quickly.

underlines my belief that Python, however useful it is, is not the ideal
language to learn about Object Oriented software development.

I guess that depends on whether you learn best from a gentle learning
curve with incremental gains in knowledge, or by immersing yourself in an
entirely unfamiliar environment with a steep learning curve to "sink or
swim".

Well as you seem to be so concerned with terminology I'd have to
disagree with you here. An interface (in computing) has any number of
meanings, hardware interfaces, software interfaces the HCI etc etc.

All of which have in common that they are a layer (hardware, software, or
something else) between two entities (objects, hardware components,
people, substances, environments, etc.).

Which is exactly what a facade is.

In
some languages an interface is a non functional unit of compilation that
describes the methods an implementing class must provide.

And even in those languages (Pascal, for example) an interface is also an
interface, not just an instruction to the compiler stating what interface
elements are required.

A facade on
the other hand aggregates a number of fine grained operations that often
implement the business logic of an application into coarser grained
methods that can be called further up the implementation stack.

Which makes it an interface to those fine-grained operations.

Just because the word "interface" is a reserved word in Pascal with a
specific technical meaning and "facade" is not does not mean that the
general term "interface" does not also apply to facades.

More
importantly, what goes on behind a facade can be completely changed
without affecting anything that uses the facade thereby enhancing
maintainability. (I'm trying really hard not to use buzzwords here).

Which is exactly the point of an interface. You can change the
implementation behind the interface (the fine-grained operations) without
needing to change the higher-level facade operations.

I'm not arguing against the usefulness of "facades". I am questioning why
they need to be singled out as a named "design pattern" instead of just
one mere example of a more general, less specific technique of building
an interface to another system.

You have a complicated, fine-grained system which is difficult to use?
Write an interface, then talk to the interface.

You have a simple, but buggy, system, and need a layer of code to work
around the bugs? Write an interface, then talk to the interface.

You have a system which changes rapidly? Write an interface, and talk to
the interface.

There's no need to teach multiple different design patterns in isolation:
"facade", "adaptor", "bridge", "connector", "proxy"... They're all the
same pattern. If you learn the general idea of an interface, the rest are
obvious. Or at least more clear and less jargon.
 
S

Steven D'Aprano

er, the point I was trying to make is that when you say 'interface' it
could mean so many things. If you say 'facade' everyone knows exactly
what you are talking about. And that is EXACTLY the point.

The whole point of design patterns is to avoid getting stuck in
incidental implementation details of a particular library or class and
look for higher-level design patterns.

The same applies to facade -- it's just a special case of the interface
pattern. Why get stuck in incidental implementation details of the
particular *kind* of interface layer you need?

Obviously the person writing the interface/facade/adaptor/whatever needs
to understand the implementation details. But the people using the
interface don't.

Why waste brain CPUs trying to decide whether a particular interface is a
facade, an adaptor, a bridge, a proxy, ... ? Especially since in real-
life code, any such interface is going to include elements of all of the
above. Take this example from Wikipedia's article on Facade pattern:

========= ========
Pattern Intent
========= ========
Adapter Converts one interface to another so that it matches
what the client is expecting
Decorator Adds responsibility to the interface without altering it
Facade Provides a simplified interface
========= ========

It's rare that the intent is as pure as that. Normally it will be:

"Simplify the interface, oh and also change the API of these three
methods to match this other library, and add a couple of helper methods,
and while you're at it, this method has a bug that upstream refuses to
patch, do something about that."

So is that a facade or an adaptor, or something else?
 
M

Mark Lawrence

Please trim unnecessary quoted text.

We don't need to see the entire thread of comment/reply/reply-to-reply
duplicated in *every* email.

Point taken, sorry.
 
S

Steven D'Aprano

On 06/08/12 13:19, rusi wrote: nouns.html

http://bpfurtado.livejournal.com/2006/10/21/

Unfortunately the author (Bruno Furtado) has missed the point. He seems
to think that Kingdom of Nouns ("the Rant") is an anti-OO screed. It is
not. There is more to OO than Java, and criticism of Java does not mean
"objects are bad".


Nor is it that Kingdom of Nouns believes the problem is "Two lines per
source code file!!!". It isn't just that two extra lines when you declare
a function. It is the extraneous, unnecessary extra layer each time you
read (or write, but mostly read) the method, and the ever-more abstract,
deep layers of Builders, Getters, Setters, Doers and so forth.

In Python, occasionally you will come across code like this:

value = time.time()

which is the time function in the time module. Pretty skanky, right? It's
not likely that you have a whole bunch of spam.time, foo.time,
physics.time etc. in your code base, right? If you do, then maybe this is
justified, but how often does that happen?

Having that duplicated time.time is a code smell that says "you might
have too many code layers here, better look at this a bit more closely".

Now imagine if this was a more Java-ish language:

value = time.time.time()

where you have method time of class time in module time. And you have to
call it that way *all the time* (pun not intended).

That's not so much a "might" have too many layers, as "almost certainly".

In Java, all those dot look-ups happen at compile time and are fast. In
Python, they happen at runtime, and while they're still often fast,
sometimes they can be slow. But that's not the real problem. The real
problem is reading and writing it.

Python solves that two ways:

1) Modules, classes, methods and functions are first-class objects, so
you can do this:

from time import time
# or if you prefer, "import time; time = time.time"
value = time()


2) It doesn't force you to use the same number of layers for
*everything*. If you have code that will benefit from two, or three, or
seventeen, layers, you are free to do so:

value = (time.time() + spacetime.Time.time() - Spam.time.flavour()
+ Cube.time())

And if not, then don't:

value = time() + spacetime.time() - flavour() + Cube.time()


It is this which is the point of Kingdom of Nouns. It is not an anti-OO
screed. It is not an argument against namespaces, or encapsulation, or
especially not that Java methods take an extra "Two lines per source
file". It is that Java forces a single mental model on you, all the time,
whether it makes for better, more readable code or not.
 
S

Steven D'Aprano

On 07/08/12 06:19, Steven D'Aprano wrote: [...]
But what *really* gets me is not the existence of poor terminology. I
couldn't care less what terminology Java programmers use among
themselves.

I'd be most grateful if you could park the whole 'This person is a 'Java
developer so must be a moron thing' it's getting a bit wearing.

Lipska, it's not always about you.

I've been hanging around this forum for, oh, at least six years now.
Trust me, you're not the first Java developer brave enough to poke their
head up :)

Java coders who come here tend to talk about "instance variables". C++
coders tend to talk about "members". Haskell people don't tend to talk
much about objects at all. And PHP coders tend to talk about how they saw
Spot run.

(I kid. Sorry PHP coders, I couldn't resist.)

It's not about being a moron. Anyone new to a language is going to carry
across preconceptions from their previous language, and use the
terminology they're used to. I've seen more than one Lisper assume that
Python lists are linked lists and wonder how to call car and cdr, and
nobody is accusing Lispers of being dumb. And I'm not going to even try
to describe the misconceptions I had learning Python, coming from a
background of Pascal, RPN and Hypertalk -- the first two languages
weren't OOP, and Hypertalk's OOP model was *very* different from Python's.

Don't think that every time I mention Java it's a dig at you.
 
S

Steven D'Aprano

I think you've entirely missed the point of Design Patterns.

Perhaps I have. Or perhaps I'm just (over-)reacting to the abuse of
Patterns:

http://c2.com/cgi/wiki?DesignPatternsConsideredHarmful

or maybe I'm just not convinced that Design Patterns as described by the
Go4 are as important and revolutionary as so many people seem to believe:

http://perl.plover.com/yak/design/

or that they are a crutch for underpowered languages:

http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatures

I haven't read the Gang of Four book itself, but I've spent plenty of
time being perplexed by over-engineered, jargon-filled code, articles,
posts and discussions by people who use Design Patterns as an end to
themselves rather than a means to an end. (Singleton is notoriously bad
in that way.)

On the other hand, as I think I've stated before, the design patterns
themselves aren't *necessarily* bad. They're just problem solving
techniques and common idioms.

I think that as languages get more powerful, "Design Patterns" just
become language features, and people stop talking about them. Nobody
talks about Function Pattern, but everyone uses it. In Python, we don't
talk about the Iterator Pattern. We just use iterators.

No one claims that the Go4 DP book introduced Builders, Singletons,
Facades. The point was to identify _and name_ such patterns, so
programmers could actually talk about repeated behaviour.

I'm pretty sure that people could talk about good coding design before
the Gof4. As you say, they didn't invent the patterns. So people
obviously wrote code, and talked about algorithms, without the Gof4
terminology.

I don't think that "Memento Pattern" is any more clear than "save and
restore".

When you have a few standard patterns, everyone can know what they are.
When you start getting into multiple dozens, it's not so clear to me that
they are all *standard* any more.

http://c2.com/cgi/wiki?CategoryPattern

And the ever-finer distinctions between variations on patterns. Without
looking them up, what are the difference between Default Visitor,
Extrinsic Visitor, Acyclic Visitor, Hierarchical Visitor, Null Object And
Visitor, and regular old Visitor patterns? -- and no, I did not make any
of them up.
 
C

Chris Angelico

I'm still undecided over the whole 'User' thing actually, I don't think I
can see a time when I will have a User Class in one of my systems but as I
don't want to get 'dogmatic' about this I remain open to any ideas that
might include such a Class.

Person however is an entirely different matter and will never appear in my
systems in any way shape or form ...this is not dogma, it's a fact.

This makes little sense to my mind. If you can have a "class User:",
why can you not have a "class Person:" ?

Now, that said, I can't remember the last time I actually had a class
called "Person" in anything other than a demo. But that's merely
because of terminology; I've had classes representing human beings,
but named according to what part these people play in the system
(Customer, Employee (haven't done that one, actually, but there's no
reason not to), User, Etcetera, Etcetera, Etcetera... is an Etceterer
someone who practices Etcetery?), and these classes are as
well-defined as any others.

Perhaps it would help to think about these things not as turning a
person into an entity, but as "retaining the data related to a
Person". The Person class details what data you store about a person,
a Person instance stores that data about one particular person. This
works for other things; a QueueEntry isn't actually standing in queue,
but it holds the data you store about the thing that is.

Or maybe that doesn't help, in which case just ignore it.

ChrisA
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,017
Latest member
GreenAcreCBDGummiesReview

Latest Threads

Top