Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 10, 2012 13:48:25

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

Нужно вместе с аттрибутом (обычный аттрибут, функция, свойство) хранить дополнительную информацию. Но если это свойство (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
Как лучше сделать что-нибудь подобное?



Офлайн

#2 Янв. 10, 2012 14:09:44

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

Если как в примере - текстовые поля, то чем не устраивает стандартный __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__

Офлайн

#3 Янв. 10, 2012 14:36:31

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

Просто там будет не только description, а еще другие аттрибуты.



Офлайн

#4 Янв. 10, 2012 15:29:02

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

Вот что пока придумал. Но по-моему эт фигня какая-то

# -*- 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)

Офлайн

#5 Янв. 12, 2012 10:34:22

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

Второй вариант через дескрипторы

# -*- 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
Если кто-нибудь знает еще варианты, подскажите



Офлайн

#6 Янв. 12, 2012 16:54:07

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

Как-то сильно попахивает костылями )
Зачем такое нужно?

Офлайн

#7 Янв. 12, 2012 17:16:05

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

Мне нужно хранить дополнительную информацию об аттрибутах объекта. Коду, который будет использовать данные объекты нужно знать тип аттрибутов.



Офлайн

#8 Янв. 12, 2012 17:19:32

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

svas
знать тип аттрибутов
isinstance() ?

Офлайн

#9 Янв. 12, 2012 17:24:06

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

нет, эти аттрибуты будут в основном типа str. Но они могут быть однострочными и многострочными. Код, который будет использовать данные объекты - парсер протокола. Взависимости от типа аттрибута считывать надо или одну строку, или много строк. Как-то так.



Офлайн

#10 Янв. 12, 2012 17:37:47

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Добавление аттрибутов к свойству (property)

На вскидку - два класса MultiLineReader и SingleLineReader, имеющие как минимум метод read.
В классе-описании вашего протокола - атрибуты - инстансы этих классов. Код получает обьект-описатель и вызывает .read() для каждого атрибута.

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version