2010-01-30 19 views
16

Jak sprawdzić, czy obiekt jest instancją obiektu Named tuple?Python: jak sprawdzić, czy obiekt jest instancją o nazwie zw.

+0

Czy trzeba wiedzieć absolutnie, lub jest heurystyczny w porządku? Jeśli to drugie, możesz sprawdzić np. obj._asdict .__ doc__ == 'Zwróć nowy uporządkowany dokument, który odwzorowuje nazwy pól na ich wartości "(prawdopodobnie również inne czynniki). –

+0

Oczywiście, oczywiście. Ale ponieważ używałbym tego "sprawdzenia" tylko w instrukcji "assert" (piszę rozszerzenie na namedtuples .., który mixin zapewnia, że ​​jest używany z nazwanątaką jako jego rodzącą klasą podstawową), kontrola heurystyczna może być również w porządku. Myślę, że warto dodać swoją kontrolę "__doc__" do kodu Alexa poniżej. –

+4

FWIW, jest to zgłoszenie jako "błąd" (nie jestem pewien, czy się z tym zgadzam): http://bugs.python.org/issue7796 – bernie

Odpowiedz

19

Wywołanie funkcjęcollections.namedtuple daje nowy typ, który jest podklasę tuple (i żadnych innych klasach) z członkiem nazwie _fields to jest krotka, której elementy są wszystkie ciągi. Więc można sprawdzić dla każdego z tych rzeczy:

def isnamedtupleinstance(x): 
    t = type(x) 
    b = t.__bases__ 
    if len(b) != 1 or b[0] != tuple: return False 
    f = getattr(t, '_fields', None) 
    if not isinstance(f, tuple): return False 
    return all(type(n)==str for n in f) 

to możliwe jest uzyskanie fałszywie dodatni od tego, ale tylko wtedy, gdy ktoś wychodzi z siebie, aby typ, który wygląda dużo jak nazwana krotka, ale nie jest jedna ;-).

+0

Prawidłowo. Zastanawiam się również, dlaczego wygenerowany typ nie został wyprowadzony z klasy znaczników 'NamedTuple', której definicja byłaby po prostu' Class NamedTuple (tuple): pass' .. po prostu dla ułatwienia nam sprawdzenia, czy obiekt jest nazwany krotko lub nie. –

+2

Dlaczego projektanci namedtuple powinni sprawić, że będzie to typecheckable, Sridhar? Zazwyczaj należy unikać typowania w Pythonie, ale w tym przypadku nic nie jest w ogóle użyteczne - nazwana nazwa z polami "x" i "y" oraz jedna z polami "koszt", "cena" i "ilość" będzie zamienny. Jedynym poziomem, do którego są one zamienne, jest to, że obie są krotkami. Nawet w przypadku użycia z klasami generowanymi przez fabrykę namedtuple, są one zwyczajnymi klasami z uzasadnionych powodów i mogą być używane podobnie jak podobne ręcznie wykonane klasy. –

+0

@Mike: Piszę rozszerzenie do nazwanych krotek .. które mixin zapewnia, że ​​jest używany z nazwaną krotką jako rodzajem klasy rodzeństwa. Tak więc potrzebuję go tylko do stwierdzenia, że ​​mixin nie jest niewłaściwie używany z innymi typami. –

3

Jeśli musisz sprawdzić przed wywołaniem nazwanych na nim konkretnych funkcji, po prostu zadzwoń do nich i zamiast tego złap wyjątek. To jest preferowany sposób zrobienia tego w pythonie.

+0

Moja odpowiedź do Mateusza powyżej wyjaśnia, gdzie używam tego czeku. –

0

używam

isinstance(x, tuple) and isinstance(x.__dict__, collections.abc.Mapping) 

co dla mnie wydaje się najlepiej odzwierciedlać słownika aspekt natury o nazwie krotki. Wydaje się być odporny na niektóre możliwe przyszłe zmiany, a także może współpracować z wieloma trzecimi, nazwanymi, pięcioklasowymi klasami, jeśli takie rzeczy się zdarzają.

+1

Spowoduje to błąd, gdy 'x = (1,2,3)' – kolypto

3

Zdaję sobie sprawę, to jest stary, ale okazało się to przydatne:

from collections import namedtuple 

SomeThing = namedtuple('SomeThing', 'prop another_prop') 
SomeOtherThing = namedtuple('SomeOtherThing', 'prop still_another_prop') 

a = SomeThing(1, 2) 

isinstance(a, SomeThing) # True 
isinstance(a, SomeOtherThing) # False 
+0

Jeśli czegoś nie brakuje, wydaje się, że jest to najlepsza i najbardziej zwięzła odpowiedź. Nazwanytyp tworzy nowy typ, a isinstance sprawdzi, czy coś jest tego typu. –

Powiązane problemy