Jak sprawdzić, czy obiekt jest instancją obiektu Named tuple?Python: jak sprawdzić, czy obiekt jest instancją o nazwie zw.
Odpowiedz
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 ;-).
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. –
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. –
@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. –
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.
Moja odpowiedź do Mateusza powyżej wyjaśnia, gdzie używam tego czeku. –
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ą.
Spowoduje to błąd, gdy 'x = (1,2,3)' – kolypto
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
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. –
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). –
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. –
FWIW, jest to zgłoszenie jako "błąd" (nie jestem pewien, czy się z tym zgadzam): http://bugs.python.org/issue7796 – bernie