Уведомления

Группа в Telegram: @pythonsu

#1 Июль 5, 2013 21:10:53

f1aky
Зарегистрирован: 2013-01-26
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

property и super

имеем два класса

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

как быть??

P.S. знаю что можно так
class B(A):

@propety
def x(self):
return A.x.fget(self) * 2
но мне надо через super.

Отредактировано f1aky (Июль 8, 2013 15:23:51)

Офлайн

#2 Июль 5, 2013 22:25:54

f1aky
Зарегистрирован: 2013-01-26
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

property и super

погуглил понял, что через 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)
2.
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
Первый метод как по мне лудче юзать когда пару проперти атрибутов, намного нагляднее будет. Второй конда много проперти атрибутов, магия, но меньше гемороя и лишнего кода.

Офлайн

#3 Июль 5, 2013 23:24:44

f1aky
Зарегистрирован: 2013-01-26
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

property и super

переписал метакласс, теперь если 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)

Офлайн

#4 Июль 5, 2013 23:39:13

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

property и super

f1aky
>>>b= b()
после этого не читал, не люблю когда показывают не тот код что нужно. Пожалуйста, оформляйте пост корректно.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#5 Июль 6, 2013 00:43:51

f1aky
Зарегистрирован: 2013-01-26
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

property и super

вам показывать сотни строк кода? вы их будите смотреть?? я не уверен.
про отпечатку извените, исправил.

Офлайн

#6 Июль 8, 2013 05:39:53

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

property и super

f1aky
вам показывать сотни строк кода? вы их будите смотреть?? я не уверен.про отпечатку извените, исправил.

>>>b.x
>>> b.t

что такое b.t мы должны догадаться?



Офлайн

#7 Июль 8, 2013 15:24:39

f1aky
Зарегистрирован: 2013-01-26
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

property и super

сорь, писал ночью, вот и опечатки такие

Офлайн

#8 Июль 8, 2013 15:52:35

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

property и super

f1aky
сорь, писал ночью, вот и опечатки такие
Вот теперь вконец запутал!
Код из стартового поста выполняется без ошибок



Офлайн

#9 Июль 8, 2013 17:20:36

f1aky
Зарегистрирован: 2013-01-26
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

property и super

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

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version