2009-06-15 11 views
26

Funkcja powinna wybierać wiersze w tabeli na podstawie nazwy wiersza (kolumna 2 w tym przypadku). Powinien być w stanie wziąć jedną nazwę lub listę nazw jako argumenty i poprawnie nimi zarządzać.Obsługa jako argument listy lub pojedynczej liczby całkowitej

To jest to, co mam teraz, ale idealnie nie byłoby to kod duplikowane i coś wyjątkami byłyby wykorzystywane w sposób inteligentny, aby wybrać odpowiedni sposób obsłużyć argument wejściowy:

def select_rows(to_select): 
    # For a list 
    for row in range(0, table.numRows()): 
     if _table.item(row, 1).text() in to_select: 
      table.selectRow(row) 
    # For a single integer 
    for row in range(0, table.numRows()): 
     if _table.item(row, 1).text() == to_select: 
      table.selectRow(row) 

Odpowiedz

18

Właściwie zgadzam się z Andrew Hare powyżej, wystarczy podać listę z jednym elementem.

Ale jeśli naprawdę musisz zaakceptować listę nieistniejącą, to może zamieniasz ją w listę?

def select_rows(to_select): 
    if type(to_select) is not list: to_select = [ to_select ] 

    for row in range(0, table.numRows()): 
     if _table.item(row, 1).text() in to_select: 
      table.selectRow(row) 

Kara za wydajność robi „w” na liście pojedynczego elementu nie może być wysoka :-) Ale to ma podkreślić jedną rzecz, może warto rozważyć, jeśli robi „to_select "lista może być długa: rozważ rzucenie jej do zestawu, aby wyszukiwanie było wydajniejsze.

def select_rows(to_select): 
    if type(to_select) is list: to_select = set(to_select) 
    elif type(to_select) is not set: to_select = set([to_select]) 

    for row in range(0, table.numRows()): 
     if _table.item(row, 1).text() in to_select: 
      table.selectRow(row) 

----- N

11

zrobiłbym tylko:

def select_rows(to_select): 
    # For a list 
    for row in range(0, table.numRows()): 
     if _table.item(row, 1).text() in to_select: 
      table.selectRow(row) 

i oczekuj, że argument będzie zawsze listą - nawet jeśli jest to tylko lista jednego elementu.

Pamiętaj:

Łatwiej prosić o przebaczenie niż pozwolenie.

+1

+1 ... znacznie łatwiej jest utrzymać tylko jeden zestaw kodu do wykonania zadania, a jeszcze więcej pythonic; niech eksploduje, jeśli ktoś wywoła to wbrew dokumentom. Jeśli naprawdę potrzebna jest funkcja, która akceptuje jedną liczbę całkowitą jako argument, zrób drugi o nazwie "def select_row (to_select)" i poproś go o listę "to_select" jako listę, a następnie wywołaj select_rows. –

14

Można przedefiniować swoją funkcję podjąć dowolną liczbę argumentów, tak:

def select_rows(*arguments): 
    for row in range(0, table.numRows()): 
     if _table.item(row, 1).text() in arguments: 
      table.selectRow(row) 

Następnie można przekazać jeden argument takiego:

select_rows('abc') 

wielu argumentów, takich jak ten:

select_rows('abc', 'def') 

A jeśli już masz t:

items = ['abc', 'def'] 
select_rows(*items) 
+0

+1 Takie podejście lepiej niż Andrew Hare'a ...Problem może być, jeśli trzeba przekazać więcej argumentów do tej samej funkcji, a nie tylko listy/pojedynczego argumentu. Ale możesz albo mieć je wcześniej, albo użyć argumentów słów kluczowych, tj. ** kwargs. – Jaime

+0

Ta odpowiedź jest wyraźnie lepsza. +1 Kod samokodujący się. * Args błaga o iterację. – tortal

3

pójdę wraz z wersją Sharkey, ale użyć trochę więcej kaczka wpisując:

def select_rows(to_select): 
    try: 
     len(to_select) 
    except TypeError: 
     to_select = [to_select] 

    for row in range(0, table.numRows()): 
     if _table.item(row, 1).text() in to_select: 
      table.selectRow(row) 

ta ma tę zaletę w pracy z dowolnego obiektu który obsługuje operator in. Również poprzednia wersja, jeśli zostanie podana krotka lub inna sekwencja, po prostu zapakuje ją na listę. Wadą jest to, że za stosowanie wyjątków jest ograniczona wydajność.

+0

Ten problem dotyczy unicodes i stringów. cf: http://stackoverflow.com/questions/305359/correct-way-to-detect-sequence-parameter/425567#425567 –

+0

Ważny punkt, powinien przynajmniej być "na (liście, krotce)" ... lub może "nie w (łańcuch, unicode)". Najlepiej byłoby, gdybyś spojrzał bezpośrednio na "czy to nic nie wspiera" w "", jak przypuszczam. – NickZoic