Перегрузка поведения в списке? - PullRequest
1 голос
/ 26 августа 2010

Мне поручено создать модель аппаратной клетки. Каждая клетка содержит N слотов, каждый слот может содержать или не содержать карту.

Я бы хотел смоделировать клетку, используя список. Каждый индекс списка будет соответствовать номеру слота. cards[0].name="Card 0" и т. Д.

Это позволило бы моим пользователям запрашивать модель через простые списки. Например:

for card in cards:
    print card.name

Мои пользователи, которые не являются опытными пользователями Python, будут взаимодействовать с моделью в режиме реального времени, поэтому нецелесообразно иметь индекс списка, не соответствующий заполненной карте. Другими словами, если пользователь удаляет карточку, мне нужно сделать что-то, что будет означать, что карточка не заполнена & ndash; мой первый импульс состоял в том, чтобы установить элемент списка на None.

Боссману нравится эта схема, но он не в восторге от того, что понимание списка выше не удалось, если пропала карта. (Что он и делает в настоящее время.) Он еще менее поддерживает требование, чтобы пользователи выучили достаточно Python для создания выражений понимания списка, которые будут игнорировать None.

Я думал подкласс list класса, чтобы создать newclass. Он будет работать точно так же, как список, за исключением того, что for card in cards будет возвращать только те элементы, для которых не установлено None.

Может, кто-нибудь продемонстрирует, как перегрузить класс списка, чтобы списочные выражения, вызываемые в подклассе, игнорировали None? (Мои навыки Python уже начали ухудшаться, когда я пытаюсь это сделать.)

Кто-нибудь может предложить лучший подход?

Ответы [ 4 ]

8 голосов
/ 26 августа 2010
>>> class MyList(list):
...     def __iter__(self):
...         return (x for x in list.__iter__(self) if x is not None)
... 
>>> 
>>> ml = MyList(["cat", "dog", None, "fox"])
>>> for item in ml:
...     print item
... 
cat
dog
fox

>>> [x for x in ml]
['cat', 'dog', 'fox']
>>> list(ml)
['cat', 'dog', 'fox']
2 голосов
/ 26 августа 2010

Вы можете предоставить генератор / итератор для этого.

def installed(cage):
    for card in cage:
        if card:
            yield card

cards = ["Adaptec RAID", "Intel RAID", None, "Illudium Q-36 Explosive Space Modulator"]

# print list of cards
for card in installed(cards):
    print card
1 голос
/ 26 августа 2010

Вы можете сделать что-то вроде этого, чтобы получить имена, если вы используете 2.6 или новее:

names = [x.name for x in cards if x is not None]

Это должно приблизиться к тому, что вы ищете, я думаю.

0 голосов
/ 26 августа 2010

Возможно, определите функцию (предполагая, что карты - это глобальная переменная?!?):

def pcards():
    for card in cards:
        if card:
            print card.name

, поэтому ваши пользователи могут просто набрать pcards(), чтобы получить список.

...