Найти - Пользователи
Полная версия: Добавление аттрибутов к свойству (property)
Начало » Python для новичков » Добавление аттрибутов к свойству (property)
1 2
svas
Нужно вместе с аттрибутом (обычный аттрибут, функция, свойство) хранить дополнительную информацию. Но если это свойство (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
Как лучше сделать что-нибудь подобное?
s0rg
Если как в примере - текстовые поля, то чем не устраивает стандартный __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__
svas
Просто там будет не только description, а еще другие аттрибуты.
svas
Вот что пока придумал. Но по-моему эт фигня какая-то
# -*- 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')
Посоветуйте какой-нибудь способ получше.
svas
Второй вариант через дескрипторы
# -*- 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
Если кто-нибудь знает еще варианты, подскажите
s0rg
Как-то сильно попахивает костылями )
Зачем такое нужно?
svas
Мне нужно хранить дополнительную информацию об аттрибутах объекта. Коду, который будет использовать данные объекты нужно знать тип аттрибутов.
s0rg
svas
знать тип аттрибутов
isinstance() ?
svas
нет, эти аттрибуты будут в основном типа str. Но они могут быть однострочными и многострочными. Код, который будет использовать данные объекты - парсер протокола. Взависимости от типа аттрибута считывать надо или одну строку, или много строк. Как-то так.
s0rg
На вскидку - два класса MultiLineReader и SingleLineReader, имеющие как минимум метод read.
В классе-описании вашего протокола - атрибуты - инстансы этих классов. Код получает обьект-описатель и вызывает .read() для каждого атрибута.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB