2016-02-16 2 views
0

Я хочу, чтобы создать конкретный экземпляр класса, который наследуется от другого конкретного класса, который, в свою очередь, наследуется от абстрактного класса.Установка значений унаследованных свойств

Основная картина:

from abc import ABCMeta, abstractproperty 

class Foo(object): 
    __metaclass__ = ABCMeta 

    @abstractproperty 
    def x(self): 
     pass 

    @abstractproperty 
    def y(self): 
     pass 

class Bar(Foo): 
    x = None 
    y = None 

    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

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

    @x.setter 
    def x(self, value): 
     self.x = value 

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

    @y.setter 
    def y(self, value): 
     self.y = value 

class Baz(Bar): 

    def __init__(self): 
     super().__init__(x=2, y=6) 


a = Baz() 

Когда я пытаюсь создать экземпляр Baz я получаю ошибку RecursionError: maximum recursion depth exceeded. (А также предупреждение pylint рассказывал мне о том, что подписи сеттеров не совпадают подписи базового класса)

Однако, если я удалить сеттеры, я получаю сообщение об ошибке self.x = x AttributeError: can't set attribute

Что такое правильный шаблон для этого?

+0

Что вы ожидали от установщика для 'x', который устанавливает' x', вызывающего setter для 'x', который устанавливает' x', вызывающего setter для ... Это не связано с наследованием, t работать в автономном классе. – jonrsharpe

+0

Что-то очень похоже на это. Я не понимаю, как сделать 'x' доступным, без установки для' x'. – Batman

+0

У вас должен быть еще один атрибут, который содержит базовое значение (или, учитывая, что getter и setter ничего не делают, просто прекратите использовать свойство - это не Java!) – jonrsharpe

ответ

1

Вы должны изменить имена для й()/у() методы или для й/у свойств, например, переименовать

class Bar(Foo): 
    x = None 
    y = None 

To:

class Bar(Foo): 
    x_val = None 
    y_val = None 

И переименовывать ссылки к х/у.

1

Что вы делали в основном:

def x(): 
    return x() 

Это произошло потому, что ваш def x переопределен в x = None, поэтому х функция (свойство), который называет себя. Избегайте этого, используя другой атрибут (по-разному) для хранения фактического значения x.

Пример из питона документации (https://docs.python.org/3.5/library/functions.html#property):

class C: 
    def __init__(self): 
     self._x = None 

    @property 
    def x(self): 
     return self._x 

    @x.setter 
    def x(self, value): 
     self._x = value 

Примечание: имена атрибутов, начинающиеся с подчеркивания следует рассматривать как «частный» и не должны быть доступны непосредственно за пределами класса. Но это всего лишь конвенция для программистов, технически это просто нормальные атрибуты, и вы можете делать все, что хотите, но приятно следовать какой-то конвенции, не так ли?