TerrorToaster
TerrorToaster

Reputation: 13

Python - Defining an Objects Return Value

I am trying to implement a very basic Java-like Dimension-Class in Python:

class Dimension(object):
    def __init__(self, width, height):
        self.__width = width
        self.__height = height

    @property
    def width(self):
        return self.__width
    @property
    def height(self):
        return self.__height
d = Dimension(800, 400)

print d.width
print d.height

This works fine: d.width returns an int=800, d.height returns an int=400. But how do I define, that d should return a tuple=(800,400) instead of <__main__.Dimension object at 0xXXXXXXXX>?

Is there an in-built class function similar to __repr__ for it? How do I define the returned value of a custom class? Or do I have to implement a new type?

Thank you

Upvotes: 1

Views: 3199

Answers (3)

Zach Gates
Zach Gates

Reputation: 4130

If you want your class to behave as a tuple, inherit from tuple:

class Dimension(tuple):

then override the __new__ method to manipulate the creation:

def __new__(cls, width, height):
    tuple.__new__(cls, (width, height))

Leaving you with:

class Dimension(tuple):

    def __new__(cls, width, height):
        return tuple.__new__(cls, (width, height)) # create tuple with 2 items

    def __init__(self, *args):
        self.width = args[0] # width is the first argument passed
        self.height = args[1] # height is the next

>>> d = Dimension(800, 400)
>>> print(d)
(800, 400)
>>> print(d.width)
800
>>> print(d.height)
400

Upvotes: 4

emre.
emre.

Reputation: 1296

The closest thing that i can think of to what you described is using namedtuples

In [1]: from collections import namedtuple

In [2]: Dimension = namedtuple("Dimension", ('width', 'height'))

In [4]: d = Dimension(800, 400)

In [5]: d.width
Out[5]: 800

In [6]: d.height
Out[6]: 400

In [7]: d
Out[7]: Dimension(width=800, height=400)

In [8]: tuple(d)
Out[8]: (800, 400)

In [11]: w, h = d

In [12]: w, h
Out[12]: (800, 400)

Does this work for you? You could find more info about namedtuples here: https://docs.python.org/2/library/collections.html#collections.namedtuple

Upvotes: 2

a_guest
a_guest

Reputation: 36259

I suggest implementing __iter__ for conversion to tuple:

class Dimension:
    # Other code goes here.

    def __iter__(self):
        return iter([self.width, self.height])

Note that I made width and height direct attributes of Dimension instead of using @property.

Example:

>>> d = Dimension(1, 2)
>>> tuple(d)
(1, 2)

Upvotes: 0

Related Questions