Форум сайта python.su
имеем два класса
class A(object):
@property
def x(self):
return 1
class B(A):
@property
def x(self):
return super(B, self).x * 2
>>>b= B()
>>>b.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in t
TypeError: must be type, not classobj
class B(A):
@propety
def x(self):
return A.x.fget(self) * 2
Отредактировано f1aky (Июль 8, 2013 15:23:51)
Офлайн
погуглил понял, что через super никак, это баг и он не исправлен.
нашел два обходных пути, может кому пригодиться:
1.
class A_(object):
def _get_x(self):
return 1
x = property(fget= _get_x)
class B_(A_):
def _get_x(self):
return super(B_, self)._get_x(self) * 2
x = property(fget= _get_x)
class PropertyMeta(type):
def __new__(cls, name, bases, dct):
property_dict = dict()
for k,v in dct.items():
if isinstance(v, property):
property_dict[k] = v
for base in bases:
for k, v in base.__dict__.items():
if property_dict.get(k) and isinstance(v, property):
if v.fget:
dct['_get_%s' % k] = v.fget
if v.fset:
dct['_set_%s' % k] = v.set
if v.fdel:
dct['_del_%s' % k] = v.fdel
return type.__new__(cls, name, bases, dct)
class A(object):
@property
def x(self):
return 1
class B(A):
__metaclass__ = PropertyMeta
@property
def x(self):
return self._get_x() * 2
Офлайн
переписал метакласс, теперь если ptoperty метод(getter, setter, deleter) в ребенке не определен, берет его от предка.
class PropertyMeta(type):
def __new__(cls, name, bases, dct):
property_dict = dict()
for k,v in dct.items():
if isinstance(v, property):
property_dict[k] = v
for base in bases:
for k, v in base.__dict__.items():
if property_dict.get(k) and isinstance(v, property):
p = property_dict.get(k)
for f_type in ['fget', 'fset', 'fdel']:
if getattr(v, f_type):
dct['_%s_%s' % (f_type[1:], k)] = getattr(v, f_type)
if not getattr(p, f_type):
dct[k] = cls._set_property_func(dct[k], f_type, getattr(v, f_type))
return type.__new__(cls, name, bases, dct)
@classmethod
def _set_property_func(cls, obj, key, func):
# через setattr вылитает ошибка, что обьекты из dct только для чтения
fget = obj.fget
fset = obj.fset
fdel = obj.fdel
if key == 'fget': fget = func
elif key == 'fset': fset = func
else: fdel == func
return property(fget= fget, fset= fset, fdel= fdel)
class A(object):
@property
def x(self):
return 1
@x.setter
def x(self, value):
print 'set x = %s' % value
class B(A):
__metaclass__ = PropertyMeta
@property
def x(self):
return self._get_x() * 2
@x.deleter
def x(self):
print 'del x'
>>> b=B()
>>> b.x
2
>>> b.x=10
set x = 10
>>> del b.x
del x
Отредактировано f1aky (Июль 5, 2013 23:26:12)
Офлайн
f1akyпосле этого не читал, не люблю когда показывают не тот код что нужно. Пожалуйста, оформляйте пост корректно.
>>>b= b()
Офлайн
вам показывать сотни строк кода? вы их будите смотреть?? я не уверен.
про отпечатку извените, исправил.
Офлайн
f1aky
вам показывать сотни строк кода? вы их будите смотреть?? я не уверен.про отпечатку извените, исправил.
Офлайн
сорь, писал ночью, вот и опечатки такие
Офлайн
f1akyВот теперь вконец запутал!
сорь, писал ночью, вот и опечатки такие
Офлайн
ээ действительно работает походу весь бок вышел в том, что когда я в консоле набирал забыл от А насдедовать от object
прошу закрыть этот фейл. Извеняюсь
Офлайн