Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Property setting from list causes maximum recursion depth exceeded

I have the following class:

class vehicle(object):
    def __init__(self, name):
        self.name = name
        self.kinds_list = ["tank", "car", "motorbike", "bike", "quad" ] 

    @property
    def kind(self):
        return self.kind

    @kind.setter
    def kind(self, x):
        if x in self.kinds_list:
            self.kind = x
        else:
            raise AttributeError('No attribute {0} found !'.format(y))

Setting kind causes a RecursionError: maximum recursion depth exceeded, aka stack overflow.

How to re-write the setter to make it work with fixed list only?

like image 514
Michał Węgrzyn Avatar asked Sep 24 '13 18:09

Michał Węgrzyn


1 Answers

The reason you reached the maximum recursion depth is that inside your setter, you do self.kind = ..., which recursively calls the same setter. You should store the value as some private attribute, just rename self.kind to self._kind.

class vehicle(object):
    def __init__(self, name):
        self.name = name
        self.kinds_list = ["tank", "car", "motorbike", "bike", "quad" ] 

    @property
    def kind(self):
        return self._kind

    @kind.setter
    def kind(self, x):
        if x in self.kinds_list:
            self._kind = x
        else:
            raise ValueError('{0} is an illegal kind of vehicle!'.format(y))

This is not a real private attribute like in other languages, since nothing prevents you from accessing my_vehicle._kind. By convention in python, everything starting with an underscore is private and shouldn't normally be touched outside of the class. Or as they say: python is for consenting adults ;).

I also slightly modified the error message in the setter.

like image 124
Bas Swinckels Avatar answered Nov 01 '22 08:11

Bas Swinckels