2

I'm trying to print the list created by the functions in this class- what do I need to fix? I'm getting output from the terminal along the lines of [<__main__.Person instance at 0x1004a0320>,.

class Person:
    def __init__(self,first,last,id,email):
        self.firstName=first
        self.lastName=last
        self.id=id
        self.email=email
        self.friends=[]
    def add_friend(self,friend):
        if len(self.friends)<5:
            self.friends.append(friend)
        if len(friend.friends)<5:
            friend.friends.append(self)

p1=Person("David","Waver","922-43-9873","dwaver@wsu.edu")
p2=Person("Bob","Jones","902-38-9973","bjones@odu.edu")
p3=Person("James","Smith","302-38-9103","jonsdfes@ou.edu")
p4=Person("Tim","Jack","902-38-0918","remmy@usc.edu")
p5=Person("Jim","Johnston","314-78-2343","jjohnston@fsu.edu")
p6=Person("Gina","Relent","102-38-1064","ginar@wvu.edu")
p7=Person("Greg","Morris","932-38-4473","jones@ttu.edu")

p1.add_friend(p2)
p1.add_friend(p3)
p1.add_friend(p4)
p1.add_friend(p5)
p1.add_friend(p6)
p1.add_friend(p7)

print p1.friends
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
ZCJ
  • 499
  • 2
  • 9
  • 17
  • 1
    are you trying to print the person objects or their names (or other details)? – Jason Yeo Feb 14 '12 at 01:05
  • I'm just beginning to learn about classes; getting attributes of various `person` instances into the `friends` list was the goal here, exactly how that's done isn't really what I'm worried about because it seems fairly easy to alter. – ZCJ Feb 14 '12 at 01:36
  • 1
    You are actually adding person objects into the friends list. So when you try to print the list, you see the shell displaying a list of ``. To print the attribute of the person objects you have to define `__repr__` or `__str__` in your person class. Refer to senderle's answer for more info. – Jason Yeo Feb 14 '12 at 02:16
  • So I was trying to add entire objects into the list rather than attributes? And `__repr__` allows me to just gets attributes of those instances of person into the list, whereas before I was basically taking the whole objects and trying to throw it in there? – ZCJ Feb 14 '12 at 02:18
  • 1
    yes you are adding `Person` objects into the list. Instead of printing ``, `__repr__` will tell the interpreter to print whatever you specify when you try to print an object. You can check out the [python repr docs](http://docs.python.org/reference/datamodel.html#object.__repr__) to find out more. – Jason Yeo Feb 14 '12 at 03:09

3 Answers3

7

You need to define __repr__ or __str__ in your Person class.

>>> class Person:
...     def __init__(self,first,last,id,email):
...         self.firstName=first
...         self.lastName=last
...         self.id=id
...         self.email=email
...         self.friends=[]
...     def add_friend(self,friend):
...         if len(self.friends)<5:
...             self.friends.append(friend)
...         if len(friend.friends)<5:
...             friend.friends.append(self)
...     def __repr__(self):
...         return self.firstName + ' ' + self.lastName

Then initialize the list as above...

>>> print p1.friends
[Bob Jones, James Smith, Tim Jack, Jim Johnston, Gina Relent]

This answer gives a good explanation of these functions.

Given the above post's point about the functions of __repr__ and __str__, probably the __repr__ should look more like this:

def __repr__(self):
    template = "Person('{0}', '{1}', '{2}', '{3}')"
    return template.format(self.firstName, self.lastName, self.id, self.email)

What's nice about the above is that it generates a string that, when evaluated, creates an object that has the same properties (apart from friends) as the original. For example:

>>> print p1
Person('David', 'Waver', '922-43-9873', 'dwaver@wsu.edu')
>>> Person('David', 'Waver', '922-43-9873', 'dwaver@wsu.edu')
Person('David', 'Waver', '922-43-9873', 'dwaver@wsu.edu')
Community
  • 1
  • 1
senderle
  • 145,869
  • 36
  • 209
  • 233
  • Thanks for the link. So `friends` consists of all the appended objects that went through the add_friend function in the class, but to print them in the list they need to be returned at some point? However, if I made `p1=person()` then 'p1.firstname="David"` I could `print p1.firstname`. So the fact that it's returned under `__repr__` doesn't seem to be the entire goal. I'll keep reading that link you posted. – ZCJ Feb 14 '12 at 01:22
  • 2
    @ZCJ, not quite. They're being "printed" in the code you provided. When you `print` an object, its `__repr__` method is called, and the string returned is used as the representation of the object. `` is what the default `__repr__` function returns. That hex id at the end is the memory address of the object. (It's the same thing returned by `hex(id(p1))`). For custom classes, Python expects you to provide your own `__repr__` if you want it to look right; if you don't, it just uses the default. – senderle Feb 14 '12 at 01:29
  • So the default for python is the memory address when having objects go through classes? Why don't I have to use `__repr__` for objects that go through functions? – ZCJ Feb 14 '12 at 01:33
  • 1
    @ZCJ, I'm not sure what you mean by "objects that go through classes" and "objects that go through functions." There's no difference between objects returned by functions and objects returned by classes. Strings and built-in types like lists and dictionaries have pre-defined `__repr__` functions that do more than the default. `p1.firstname` is a string, so it prints out like a string. – senderle Feb 14 '12 at 01:42
  • Maybe it's that the only things I've put through functions so far are not strings but just numbers (or variables referring to numbers) and I didn't recognize that putting strings through means you have to "condition" them in some way, in this case using `__repr__'. – ZCJ Feb 14 '12 at 01:44
  • 1
    @ZCJ, Still not quite sure what you mean by "putting strings through." When you print a list, the `__repr__` function of the list calls the `__repr__` function of the objects inside it. So strings in a list are printed as expected. But if you store a string as part of an object without a custom `__repr__` function, Python doesn't know to do that. – senderle Feb 14 '12 at 01:49
  • 1
    You seem to be very, very confused. Everything in Python is an object. Strings are objects. Instances of classes are objects. The classes themselves are objects. Functions are objects. So we start from there. Everything, being an object, can be printed. Printing something requires converting it to a string, via either the `__str__` or `__repr__` method, as appropriate. (Yes, every string has a `__str__` method - that returns itself - and a `__repr__` method.) When you don't define these methods for your class, they get the default behaviour, so that **something** appears. – Karl Knechtel Feb 14 '12 at 02:19
  • 1
    (con't) "Going through" a function or a class is a phrase that simply doesn't make any sense. Classes are blueprints for objects; you instantiate the class to get an object. Functions return objects. Either way, objects are objects. – Karl Knechtel Feb 14 '12 at 02:20
  • Okay, I'm starting to get it. Since what would really be printed if you just have `p1=Person("David","Waver","922-43-9873","dwaver@wsu.edu")` anyway? Python goes, "what string of characters should I output here?" So you have objects, but in order to be printed they need to be converted into a string of text, with letters/numbers/special characters. `__repr__` and `__str__` do that. – ZCJ Feb 14 '12 at 02:32
3

The representation of an object is given by the string returned by its __repr__() method. The string shown when the object itself is printed is the string returned from its __str__() method. Frameworks may use the string returned by the __unicode__() method for displaying the object.

class Person:
   ...
  def __repr__(self):
    return 'Person: %s, %s' % (self.lastName, self.firstName)
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
1

You need to define a __repr__ method for your class. For example, like this

class Person:
    def __repr__(self):
        return '%s, %s, %s, %s' %(self.firstName, self.lastName, self.id, 
                                  self.email)
Praveen Gollakota
  • 37,112
  • 11
  • 62
  • 61