Форум сайта python.su
9
Нужно вместе с аттрибутом (обычный аттрибут, функция, свойство) хранить дополнительную информацию. Но если это свойство (property) то ничего не получается.
Нужно примерно следующее
# -*- coding: utf-8 -*-
class SomeClass(object):
def some_func(self):
pass
#Здесь все работает
some_func.description = 'This is some_func description'
def get_value(self):
return 1
def set_value(self, val):
pass
something = property(get_value, set_value)
#А здесь не работает
#something.description = 'This is something property description'
sc = SomeClass()
print sc.some_func
print sc.some_func.description
print sc.something
#Соответственно здесь тоже ошибка
#print sc.something.description
Офлайн
25
Если как в примере - текстовые поля, то чем не устраивает стандартный __doc__?
class Foo(object):
def do_foo(self):
'Does foo'
pass
def get_bar(self):
pass
bar = property(get_bar, doc='get/set bar')
print Foo.do_foo.__doc__
print Foo.bar.__doc__
Офлайн
9
Просто там будет не только description, а еще другие аттрибуты.
Офлайн
9
Вот что пока придумал. Но по-моему эт фигня какая-то
# -*- coding: utf-8 -*-
def register_attribute(klass, attrib, attrib_type):
klass.attribute_types[attrib] = attrib_type
class BaseObjectMetaclass(type):
def __new__(self, name, bases, attrs):
attribute_types = {}
for base in bases:
if isinstance(base, BaseObjectMetaclass):
attribute_types.update(base.attribute_types)
attrs['attribute_types'] = attribute_types
return super(BaseObjectMetaclass, self).__new__(self, name, bases, attrs)
class BaseObject(object):
__metaclass__ = BaseObjectMetaclass
SHORT,LONG = range(2) #attribute type
@classmethod
def get_registered_attributes(klass):
return klass.attribute_types
@classmethod
def get_attribute_type(klass, attrib):
return klass.attribute_types[attrib]
class A(BaseObject):
@property
def attr1(self):
pass
@property
def attr2(self):
pass
register_attribute(A, 'attr1', BaseObject.SHORT)
register_attribute(A, 'attr2', BaseObject.LONG)
class B(A):
@property
def attr3(self):
pass
register_attribute(B, 'attr3', BaseObject.SHORT)
a = A()
print a.get_registered_attributes()
print a.get_attribute_type('attr1')
b = B()
print b.get_registered_attributes()
print b.get_attribute_type('attr2')
print b.get_attribute_type('attr3')
Отредактировано (Янв. 10, 2012 15:30:40)
Офлайн
9
Второй вариант через дескрипторы
# -*- coding: utf-8 -*-
class MyProperty(object):
SHORT,LONG = range(2)
def __init__(self, attrib_type, fget=None, fset=None):
self.fget = fget
self.fset = fset
self.type = attrib_type
def __get__(self, obj, objtype=None):
if obj is None:
return self
return self.fget(obj)
def __set__(self, obj, value):
self.fset(obj, value)
class A(object):
def __init__(self):
self._attr1 = None
def get_attr1(self):
return self._attr1
def set_attr1(self, value):
self._attr1 = value
attr1 = MyProperty(MyProperty.SHORT, get_attr1, set_attr1)
class B(A):
def __init__(self):
self._attr2 = None
def get_attr2(self):
return self._attr2
def set_attr2(self, value):
self._attr2 = value
attr2 = MyProperty(MyProperty.LONG, get_attr2, set_attr2)
a = A()
b = B()
a.attr1 = 5
b.attr1 = 6
b.attr2 = 7
print a.attr1, b.attr1, b.attr2
b_type = type(b)
a_type = type(a)
print a_type.attr1.type, b_type.attr1.type, b_type.attr2.type
Офлайн
25
Как-то сильно попахивает костылями )
Зачем такое нужно?
Офлайн
9
Мне нужно хранить дополнительную информацию об аттрибутах объекта. Коду, который будет использовать данные объекты нужно знать тип аттрибутов.
Офлайн
25
svasisinstance() ?
знать тип аттрибутов
Офлайн
9
нет, эти аттрибуты будут в основном типа str. Но они могут быть однострочными и многострочными. Код, который будет использовать данные объекты - парсер протокола. Взависимости от типа аттрибута считывать надо или одну строку, или много строк. Как-то так.
Офлайн
25
На вскидку - два класса MultiLineReader и SingleLineReader, имеющие как минимум метод read.
В классе-описании вашего протокола - атрибуты - инстансы этих классов. Код получает обьект-описатель и вызывает .read() для каждого атрибута.
Офлайн