2016-09-17 2 views
0

Я разрабатываю этот проект Python, где я встречаюсь с ситуацией много раз, и я задавался вопросом, есть ли лучший способ.Избегайте дополнительной строки для проверки атрибута?

Список экземпляров классов. Некоторая часть списков пуста (заполнена None). Вот список примеров.

ins_list = [ins_1, ins_2, None, ins_3, None] 

Я должен сделать некоторые подтверждения в течение всего потока программы. Есть пункты, в которых мне нужен элемент управления атрибута этих экземпляров. Но для выбора экземпляра из списка даются только индексы, и это может быть один из пустых элементов. Это приведет к ошибке при вызове атрибута. Вот пример потока программы.

ind = 2 

if ins_list[ind].some_attribute == "thing": 
    # This would give error when empty element is selected. 

я справиться с этим, используя,

if ins_list[ind]: 
    if ins_list[ind].some_attribute == "thing": 
     # This works 

Я в порядке с помощью этого. Однако программа длинная, я применяю ее сотни раз. Есть ли более простой и эффективный способ сделать это, это означает, что я создаю избыточный код и увеличивая уровень отступов без каких-либо причин. Я хочу знать, есть ли такое решение.

ответ

0

Есть эти два варианта:

Использование словаря:

Другим способом было бы использовать вместо dictionary. Таким образом, вы можете создать свой словарь, как только список будет заполнен элементами. Клавиши словаря будут значениями вашего списка, а в качестве значений вы можете использовать атрибуты элементов, которые не являются None и «No_attr» для тех, которые являются None. (Примечание: Имейте в виду, что питон словари не поддерживают дубликаты ключей, и поэтому я предлагаю ниже, чтобы сохранить в качестве ключей вашего списка индексов еще вы должны найти способ, чтобы сделать ключи быть разными)

Например для списка, как:

l = [item1,item2,None,item4] 

вы можете создать словарь:

d = {item1:"thing1", item2:"thing2", None:"No_attr", item3:"thing3"} 

Таким образом, в этом случае каждый раз, когда вам нужно будет сделать чек, вы не должны проверить два условия, но вы можете проверить только значение, например:

if d.values()[your_index]=="thing": 

Единственные против этого метода является то, что стандартные питона словари неотъемлемо неупорядоченный, что делает доступ к словарю значения по индексу немного опасно иногда - вы должны быть осторожны, чтобы не изменить форму-расположение словаря.

Теперь, если вы хотите, чтобы убедиться, что индекс остается стабильной, то вы должны хранить его каким-то образом, например, выбрать в качестве ключей из словаря индексы, как вы уже хранится атрибуты предметов - Но это то, что вам придется решать и сильно зависит от архитектуры вашего проекта.

Использование списка:

При использовании list сек, как я не думаю, что есть способ, чтобы избежать вашей, если заявление - и это не плохо на самом деле. Возможно, используйте оператор and, как уже упоминалось в другом ответе, но я не думаю, что это имеет какое-либо значение.

Также, если вы хотите использовать первый подход: if ins_list[ind].some_attribute == "thing":

Вы можете попробовать использовать и исключение зрелище, как это:

try: 
    if ins_list[ind].some_attribute == "thing": 
     #do something 
except: 
    #an error occured 
    pass 
+0

«Нет» должен существовать в списке в моей программе. Список - это предопределенный держатель данных, где элементы заполняются и опустошаются. –

0

Используйте логический оператор and.

if ins_list[ind] and ins_list[ind].some_attribute == "thing": 
    # Code 
0

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

Я хочу предложить другой способ: вы можете создать dummyclass и заменить None им. Таким образом, не будет никакой ошибки, если вы установите атрибут:

class dummy: 
    def __nonzero__(self): 
     return False 
    def __setattr__(self, k, v): 
     return 


mydummy = dummy() 
mylist = [ins_1, ins_2, mydummy, ins_3, mydummy] 

ничего не будет храниться на dummyinstances при установке атрибута

редактировать:

Если содержание исходного списка не может быть выбран, то этот класс может помочь:

class PickyList(list): 
    def __init__(self, iterable, dummyval): 
     self.dummy = dummyval 
     return super(PickyList, self).__init__(iterable) 
    def __getitem__(self, k): 
     v = super(PickyList, self).__getitem__(k) 
     return (self.dummy if v is None else v) 



mylist = PickyList(ins_list, mydummy) 
0

В этом случае я бы использовал оператор try-except, потому что EAFP(проще попросить прощения, чем разрешение). Это не сократит код yout, но это более Pythonic способ кодирования при проверке действительных атрибутов. Таким образом, вы не будете нарушать DRY (Do not Repat Yourself).

try: 
    if ins_list[ind].some_attribute == "thing": 
     # do_something() 
except AttributeError: 
    # do_something_else() 
Смежные вопросы