2010-02-03 5 views
10

Как можно расширять или подклассы namedtuples с множеством дополнительных @properties?
Для некоторых можно просто написать текст ниже; но есть много, , так что я ищу генератор или фабрику свойств. Одним из способов было бы генерировать текст от _fields и исполнять его; другой будет add_fields с тем же эффектом во время выполнения.
(Мои @props должны получить строки и поля в базе данных разбросаны по нескольким таблицам, так что rec.pname является persontable[rec.personid].pname; но namedtuples-с-смарт-полей будет иметь другое использование тоже.)расширяет Python namedtuple со многими @properties?

""" extend namedtuple with many @properties ? """ 
from collections import namedtuple 

Person = namedtuple("Person", "pname paddr") # ... 
persontable = [ 
    Person("Smith", "NY"), 
    Person("Jones", "IL") 
    ] 

class Top(namedtuple("Top_", "topid amount personid")): 
    """ @property 
     .person -> persontable[personid] 
     .pname -> person.pname ... 
    """ 
    __slots__ =() 
    @property 
    def person(self): 
     return persontable[self.personid] 

    # def add_fields(self, Top.person, Person._fields) with the same effect as these ? 
    @property 
    def pname(self): 
     return self.person.pname 
    @property 
    def paddr(self): 
     return self.person.paddr 
    # ... many more 

rec = Top(0, 42, 1) 
print rec.person, rec.pname, rec.paddr 
+2

Вы не ответили на свой вопрос? –

+0

Я не понимаю вопроса. Может быть, вы хотите, чтобы свойства отображались в кортеже? Перезагрузите getitem, если хотите. – Pepijn

+1

Я тоже смущен. Вы, кажется, делаете именно то, что должны быть, чтобы получить эффект, о котором вы спрашиваете. Какая у вас проблема? – Omnifarious

ответ

13

ответ на ваш вопрос

Как namedtuples быть продлен или подклассы с дополнительным @properties ?

: именно так вы это делаете! Какую ошибку вы получаете? Чтобы увидеть более простой случай,

>>> class x(collections.namedtuple('y', 'a b c')): 
... @property 
... def d(self): return 23 
... 
>>> a=x(1, 2, 3) 
>>> a.d 
23 
>>> 
2

Как насчет этого?

class Top(namedtuple("Top_", "topid amount personid")): 
    """ @property 
     .person -> persontable[personid] 
     .pname -> person.pname ... 
    """ 
    __slots__ =() 
    @property 
    def person(self): 
     return persontable[self.personid] 

    def __getattr__(self,attr): 
     if attr in Person._fields: 
      return getattr(self.person, attr) 
     raise AttributeError("no such attribute '%s'" % attr) 
0

Вот один подход, немного язык: превратить это в текст Python, как указано выше, и EXEC его.
(Расширение текста в текст легко сделать, и легко проверить — вы можете посмотреть на промежуточном тексте.)
Я уверен, что похожи, если не так мало таких, ссылки, пожалуйста?

# example of a little language for describing multi-table databases 3feb 
# why ? 
# less clutter, toprec.pname -> persontable[toprec.personid].pname 
# describe in one place: easier to understand, easier to change 

Top: 
    topid amount personid 
    person: persontable[self.personid] + Person 
     # toprec.person = persontable[self.personid] 
     # pname = person.pname 
     # locid = person.locid 
     # todo: chaining, toprec.city -> toprec.person.loc.city 

Person: 
    personid pname locid 
    loc: loctable[self.locid] + Loc 

Loc: 
    locid zipcode province city