-1

I have a class that represents a point that I am using to replace tuples. With tuples I can just call x, y = point How can I emulate this functionality with a class? I can have __repr__ return a tuple but it throws TypeError: __repr__ returned non-string (type tuple) if I try to call print. How is this functionality handled for tuples?

Mark Omo
  • 898
  • 2
  • 12
  • 26
  • Please read and follow the advice here: [How to create a Minimal, Complete, and Verifiable example](http://www.stackoverflow.com/help/mcve) – Bryan Oakley Mar 10 '17 at 22:45
  • 5
    This seems very confused. `x, y = some_object` is unpacking and requires an iterable type. It has nothing to do with `__repr__` or printing. – Blckknght Mar 10 '17 at 22:45
  • You could let your `Point` class inherit from `tuple` or `list`. – Aran-Fey Mar 10 '17 at 22:48

3 Answers3

5

If you want instances of your class to be usable like tuples on the right side of a multiple assignment statement like x, y = some_object, you need to make your class iterable. That behavior has nothing to do with the __repr__ of your class.

Try something like this (with whatever additional methods you need):

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __iter__(self):
        yield self.x
        yield self.y

    def __repr__(self):
        return "{}({}, {})".format(type(self).__name__, self.x, self.y)

Instances of this class are iterable, which means that an unpacking will work. They can also be printed, or turned into strings with str or repr.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
2

Don't use your own class, use a collections.namedtuple instead? The help(collections.namedtuple) even is an example about a Point type

Irmen de Jong
  • 2,739
  • 1
  • 14
  • 26
1

Unpacking is essentially iterating. Here is a sketch of how you could implement this in a Point class:

>>> class Point:
...     def __init__(self, x=0, y=0):
...         self._values = (x, y)
...     def __iter__(self):
...         return iter(self._values)
...
>>> p = Point(1,2)
>>> a,b = p
>>> a
1
>>> b
2
>>>

Edit, of course, here I just wrap a tuple, but you can unpack anything that implements the iterator protocol.

Community
  • 1
  • 1
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172