JasonArg123
JasonArg123

Reputation: 318

child class attribute different name

I want an attribute of a child class to have a different name than the same attribute of its parent class even though it means the same thing. For example, a parent class is Shape with attribute "height" and child class Circle with similar arttribute "Diameter". Below is a simplification of what I current have but I want the Circle class to use "diameter" instead of "height". What is the best way to handle this?

NOTE: I will inherit from Circle in another class that also needs to use "diameter" instead of "height". Thank you!

class Shape():
    def __init__(self, shape, bar_args, height):
        self.shape = shape
        self.height = height
        etc.

class Circle(Shape):
    def __init__(self, height, foo_args, shape='circle'):
    Shape.__init__(self, shape, height)
        self.height = height
        etc.

Upvotes: 0

Views: 125

Answers (1)

glglgl
glglgl

Reputation: 91017

You could define a property which accesses the original attribute on read and write access:

class Circle(Shape):
    def __init__(self, height, foo_args, shape='circle'):
        Shape.__init__(self, shape, height) # assigns the attributes there
        # other assignments
    @property
    def diameter(self):
        """The diameter property maps everything to the height attribute."""
        return self.height
    @diameter.setter
    def diameter(self, new_value):
        self.height = new_value
    # deleter is not needed, as we don't want to delete this.

If you want this behaviour very often and you find property handling with setter and getter too unhandy, you can go a step higher and build your own descriptor class:

class AttrMap(object):
    def __init__(self, name):
        self.name = name
    def __get__(self, obj, typ):
        # Read access to obj's attribute.
        if obj is None:
            # access to class -> return descriptor object.
            return self
        return getattr(obj, self.name)
    def __set__(self, obj, value):
        return setattr(obj, self.name, value)
    def __delete__(self, obj):
        return delattr(obj, self.name)

With this, you can then do

class Circle(Shape):
    diameter = AttrMap('height')
    def __init__(self, height, foo_args, shape='circle'):
        Shape.__init__(self, shape, height) # assigns the attributes there
        # other assignments

and the diameter descriptor will redirect all accesses to it to the named attribute (here: height).

Upvotes: 3

Related Questions