У меня есть класс, как:Override атрибут со свойством в классе питона
class Parent(object):
def __init__(self, a1 = None, a2 = None):
someInitialization()
self.a1 = a1
self.a2 = a2
def coolMethod(self):
return dosomething(self.a2)
Давайте предположим, что
- Я не хочу, чтобы изменить атрибуты родительского класса
- Я не хочу предоставлять a1 и a2 при инициализации, потому что они дороги для вычисления (и они не нужны для каждого метода родителя)
- Я не хочу помнить, какие из методов Paren т требует a1 или a2, они должны просто работать
EDIT мои фактические ограничения на самом деле не так строги, но я задаю этот вопрос также для лучшего понимания атрибутов классов, методов и т.д ..
Я использую самое простое решение без наследования инициализации:
class Child(Parent):
_propertiesCache = {'a1':None,'a2':None}
def _initProperty(self, propertyName):
value = self._propertiesCache[propertyName]
if value is None:
self._propertiesCache[propertyName]=expensiveFunction(self.b, propertyName)
return self._propertiesCache[propertyName]
@property
def a1(self):
return self._initProperty('a1')
@property
def a2(self):
return self._initProperty('a2')
def __init__(self,b):
self.b = b
someInitialization()
есть ли способ, чтобы правильно называть инициализации родительского класса? Если я использую super(Child,self).__init__()
, я получаю AttributeError: can't set attribute
. Я попытался переопределить __new__
но я всегда что-то отсутствует
class Child(Parent):
_propertiesCache = {'a1':None,'a2':None}
@classmethod
def _initProperty(cls, propertyName):
value = cls._propertiesCache[propertyName]
if value is None:
cls._propertiesCache[propertyName] = someTimeConsumingFunctionThatIDontWantToCallAtInitialization(propertyName)
return cls._propertiesCache[propertyName]
@property
def a1(self):
return self._initProperty('a1')
@property
def a2(self):
return self._initProperty('a2')
def __new__(cls):
super(Child,cls).__new__(cls)
return cls
def __init__(self,b):
self.b = b
super(Child,self).__init__(a1=self.a1, a2=self.a2)
дает мне:
>>c = Child();c.a1
<property at 0x3aa4228>
>>c.a1.fget(c)
"ValueOfa1"
Рассматривали ли вы делая 'Parent' абстрактный базовый класс, и' a1' требуемое свойство? См. Https://docs.python.org/2/library/abc.html – jonrsharpe
Можете ли вы сделать метод 'a' getter, который вычисляет' self.a', если он не существует, а затем возвращает 'self.a' ? – acdr
@jonrsharpe спасибо за предложение, это излишний для моего фактического варианта использования, но это то, на что я должен смотреть, в общем! – lib