1

Purely a cosmetic thing, but when I create a class in python, how do I control its instances' titles? e.g. for

class Foo():
    def __init__(self, name):
         self.name = name

I can then create an instance:

>> f = Foo('bar')
>> f
<Foo instance at 0x10ab41a28>

If I wanted that to return bar, what would I do? (In Django, you use the __unicode__ method of the class, but I've tried setting both __unicode__ and __str__ functions to return self.name, and while these work on their own, they don't affect the value of the class.)

futuraprime
  • 5,468
  • 7
  • 38
  • 58

4 Answers4

4

I usually define __str__ to return a string representation, and then return the string in the __repr__ method, like this:

>>> class Foo():
...     def __init__(self, name):
...          self.name = name
...     def __str__(self):
...          return '<Foo name=%s>' % self.name
...     def __repr__(self):
...          return str(self)
... 
>>> f = Foo('bar')
>>> f
<Foo name=bar>

For more info, see Difference between str and repr in Python

Community
  • 1
  • 1
jterrace
  • 64,866
  • 22
  • 157
  • 202
2

Define __repr__ instead - that will sort you out.

KL-7
  • 46,000
  • 9
  • 87
  • 74
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
1

In this case, it's not the problem with your class.

class Foo(object):
  def __init__(self, name):
    self.name = name
  def __str__(self):
    return self.name

>>> f = Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 2 arguments (1 given)
>>> f = Foo("bar")
>>> f
<__main__.Foo object at 0x7f2a9b9b7590>
>>> print(f)
bar

The problem is that by just typing f, you'll get the output of repr() instead of str(). If you want to change that, you'll need to define __repr__ instead of __str__ or __unicode__.

Usually, you'll be using the str() output anyways (print uses it, when coercing to string it gets used). repr() is really only used if you ask for it, like with:

>>> print("{0!r}".format(f))
<__main__.Foo object at 0x7f2a9b9b7590>
Jonas Schäfer
  • 20,140
  • 5
  • 55
  • 69
1

You're mixing up a few things,

You set the name of the class when you used Class Foo:. This created a class whose name was Foo.

Now, when you do f = Foo('bar') and then f, the interpreter handily calls your instance's __repr__ method:

>>> class Foo():
...  def __repr__(self):
...   return 'REPR'
... 
>>> f = Foo()
>>> 
>>> f
REPR
>>> 

Long story short, use the __repr__ method if you want to control what the interpreter returns when you write f.

If you don't, the interpreter will more-or-less do it for you:

>>> class F():
...  pass
... 
>>> f = F()
>>> f.__repr__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: F instance has no attribute '__repr__'
>>> repr(f)
'<__main__.F instance at 0x7f00381e2368>'
Thomas Orozco
  • 53,284
  • 11
  • 113
  • 116