Help understanding an Object Oriented Program example

Chris Angelico rosuav at gmail.com
Sun Oct 28 20:02:50 EDT 2012


On Mon, Oct 29, 2012 at 10:30 AM, goldtech <leegold at operamail.com> wrote:
> Hi,
>
> Trying to learn Python OOP. An example from a book, may not be
> formated after sending post but:
>
> class Contact:
>     all_contacts = []
>     def __init__(self, name, email):
>         self.name = name
>         self.email = email
>         Contact.all_contacts.append(self)
>
> OK, no I do this:
>
>>>> c = Contact('aaa','bbb')
>>>> c = Contact('ccc','ddd')
>>>> c = Contact('eee','fff')
>>>> for i in Contact.all_contacts:
>         print i.name + '  ' + i.email
>
>
> aaa  bbb
> ccc  ddd
> eee  fff
>>>>
>>>> c.name
> 'eee'

Hi! Side point before we begin: You appear to be using Python
2.something (since print is a statement, not a function), but your
book (as you mention further down) refers to Python3. I recommend you
get an interpreter that corresponds to your book, or you'll end up
tripping over a triviality :) If the book doesn't specify a particular
version, get 3.3 - it's the latest released Python, and a significant
improvement over its predecessors.

> So wouldn't be good to add a check that the var (in this case c) does
> not point to any object before creating an object to keep the list
> correct?

Depends what you mean by "correct" there. If you're expecting the list
to contain only those objects that are referenced somewhere else,
you'll have to play around with weak references and such; normally,
what's expected of code like this is that it will retain all objects
created, even if there are no other references. So in that sense, the
list's already correct.

> Also all_contacts is a class variable. I think the author is hinting
> that this would be a good idea for a contact list, But I don't fully
> see the usage of it. How would each object use a class variable like
> this? What would be the dot notation?

Exactly the way you currently are, as Contact.all_contacts - but
there's also some magic that lets you reference it from any instance:

>>> Contact("foo","foo at foo")
<__main__.Contact instance at 0x011B5030>
>>> Contact("a","a at a")
<__main__.Contact instance at 0x011BC828>
>>> c=Contact("quux","quux at example.com")
>>> c.all_contacts
[<__main__.Contact instance at 0x011B5030>, <__main__.Contact instance
at 0x011BC828>, <__main__.Contact instance at 0x011BC5D0>]

Note how all three instances are listed in one instance's all_contacts
member. (Note also that I didn't have to assign the other two to
anything - the objects still get retained in all_contacts.) A common
way to do this sort of thing is to simply use self:

class Contact:
    all_contacts = []
    def __init__(self, name, email):
        self.name = name
        self.email = email
        self.all_contacts.append(self)

As long as you don't rebind that name (eg "self.all_contacts = []"),
this will work just fine.

> I realize this is a code fragment and is no way implementable code.

Actually, it's quite workable. It's enough to paste into the
interactive interpreter and play with. That's one of Python's best
features - it's really easy to play with. And if you put parentheses
around your print argument, it'll be fully Python 3 compatible (though
when you run it in Python 2, you get an old-style class - but since
the book's assuming Py3, new-style is what you want anyway).

>>> for i in Contact.all_contacts:
        print(i.name + '  ' + i.email)

Hope that helps!

Chris Angelico



More information about the Python-list mailing list