Cóż, kanoniczne podejście w Pythonie polega na tym, aby w ogóle nie sprawdzać typu (chyba że debugujesz). Zwykle po prostu próbujesz użyć go jako łańcucha (np. Połączyć z innymi łańcuchami, drukować na konsoli itp.); jeśli uważasz, że to może się nie powieść, użyj try / else lub hasattr. To powiedziawszy, zaakceptowana odpowiedź jest kanonicznym sposobem robienia tego, czego na ogół „nie powinieneś” robić w świecie Pythona. Aby uzyskać więcej informacji, wejdź na Google „ Pisanie kaczek w języku Python” lub przeczytaj je: voidspace.org.uk/python/articles/duck_typing.shtml stackoverflow.com/questions/610883/...
Jon Coombs
9
Myślę, że pan Coombs przeoczy przykłady takie jak klasy szeregowalne inne niż JSON. Jeśli wstawiając dużą część danych przez funkcję (na kod, na którą nie można wpływać), można chcieć przekonwertować niektóre fragmenty tych danych, na przykład na <str> przed ich przekazaniem. Przynajmniej tak trafiłem na tę stronę ...
John Carrell,
2
Wydaje się, że najczęstszym powodem tego pytania jest to, że chce się rozróżnić ciągi znaków i iterowalne ciągi znaków. To trudne pytanie, ponieważ łańcuchy są iterowalnymi ciągami - łańcuch jednoznakowy jest nawet sekwencją samego siebie (ostatnim razem, gdy sprawdzałem - prawdopodobnie nie należy na nim polegać). Ale czy ktokolwiek kiedykolwiek użyłby czegoś podobnego do sznurka? Tak . Zatem odpowiedź na „Co powinienem zrobić, aby odróżnić ciągi znaków od innych iterowalnych ciągów znaków?” jest właściwie: „To zależy od tego, co próbujesz zrobić”. :-D
clacke
2
Adnotacje typu Python są teraz rzeczą. Spójrz na mypy
Sheena
Odpowiedzi:
1522
Aby sprawdzić, czy ojest instancją strlub jakąkolwiek podklasą str, użyj isinstance (byłby to sposób „kanoniczny”):
if isinstance(o, str):
Aby sprawdzić, czy typ ojest dokładnie str(wyklucz podklasy):
if type(o)is str:
Następujące działania również działają i mogą być przydatne w niektórych przypadkach:
if issubclass(type(o), str):
Zobacz funkcje wbudowane w Python Library Reference istotnych informacji.
Jeszcze jedna uwaga: w tym przypadku, jeśli używasz Python 2, możesz chcieć użyć:
if isinstance(o, basestring):
ponieważ będzie to również złapać ciągi Unicode ( unicodenie jest podklasą str; oba stri unicodesą podklasy basestring). Zauważ, że basestringnie istnieje już w Pythonie 3, gdzie istnieje ścisłe oddzielenie ciągów ( str) i danych binarnych ( bytes).
Alternatywnie, isinstanceakceptuje krotkę klas. Zwróci to, Truejeśli ojest instancją dowolnej podklasy dowolnej z (str, unicode):
str .__ podklasy __ () zwraca tylko bezpośrednie podklasy str i nie robi tego samego, co issubclass () lub isinstance (). (Aby to zrobić, musisz rekurencyjnie wywoływać .__ podklasy __ ().
Thomas Wouters
15
To dobra odpowiedź, ale myślę, że naprawdę powinna zacząć od ostrzeżenia, że zwykle nie powinieneś robić tego w Pythonie. W tej chwili wydaje się to potwierdzać założenie, że jest to „kanoniczna rzecz do zrobienia w Pythonie”, a tak nie jest.
Jon Coombs,
4
To są odpowiedzi na python2. Na przykład w python3 nie ma łańcucha bazowego.
dfrankow
4
Jaka jest różnica między instancją a „dokładnie”? Jeśli type(a) is Objectto nie jest prawdą, że tak isinstance(a, Object). Jeśli jednak type(a) is SubClassOfObjectto type(a) is Object == False, ale isinstance(a, Object) == True. Dobrze?
mavavilj
1
@mavavilj - a is boznacza, że aib są dokładnie tym samym, tzn. odniesienia do tego samego bytu w pamięci. Więc ai bmusiałaby być dokładnie taka sama klasa, a nie podklasy, jak w przypadku isinstance(). Zobacz na przykład stackoverflow.com/a/133024/1072212
Terry Brown
196
Najbardziej pythonowy sposób sprawdzić typ obiektu jest ... nie to sprawdzić.
Ponieważ Python zachęca do pisania kaczego , powinieneś po prostu try...exceptużywać metod obiektu tak, jak chcesz. Więc jeśli twoja funkcja szuka zapisywalnego obiektu pliku, nie sprawdzaj, czy jest to podklasa file, po prostu spróbuj użyć jego .write()metody!
Oczywiście czasami te ładne abstrakcje rozpadają się i isinstance(obj, cls)są tym, czego potrzebujesz. Ale używaj oszczędnie.
IMHO, najbardziej pythonicznym sposobem jest radzenie sobie z każdym podanym argumentem. W moim kodzie często nie wiem, czy otrzymuję obiekt, czy tablicę obiektów, i wewnętrznie używam sprawdzania typu, aby przekonwertować pojedynczy obiekt na listę jednoelementową.
sastanin
14
Zamiast próbować użyć metody zapisu, są chwile, kiedy chcesz to zrobić bez powodowania wyjątku. W takim przypadku możesz zrobić ... if hasattr(ob, "write") and callable(ob.write): lub zapisać dostęp do func = getattr(ob, "write", None)if callable(func): ...
nagrań
142
Wpisywanie kaczki polega na korzystaniu z biblioteki. Sprawdzanie typu polega na pisaniu biblioteki. Domena nie jest tym samym problemem.
RickyA,
16
@RickyA, nie zgadzam się. Wpisywanie kaczych polega na interakcji z obiektami za pomocą interfejsów o znanej semantyce. Może to dotyczyć zarówno kodu biblioteki, jak i kodu korzystającego z takiej biblioteki.
Oczywiście to się nie powiedzie, jeśli obiekt nie jest instancją „str”, lecz czegoś w rodzaju łańcucha. Jak unicode, mmap, UserString lub dowolny inny typ zdefiniowany przez użytkownika. Typowe podejście w Pythonie nie polega na sprawdzaniu typów.
Thomas Wouters
6
Nie musisz przepraszać, możesz odpowiedzieć na własne pytanie. SO dotyczy odpowiedzi, a nie karmy.
Eli Bendersky
2
To jest bardzo pomocne. Ponieważ różnica między isinstancei type(var) == type('')nie jest wyraźna.
sastanin
30
Po zadaniu pytania i udzieleniu odpowiedzi do Pythona dodano wskazówki typu . Wskazówki dotyczące typów w Pythonie umożliwiają sprawdzanie typów, ale w zupełnie inny sposób niż w przypadku języków typowanych statycznie. Wskazówki dotyczące typów w Pythonie kojarzą oczekiwane typy argumentów z funkcjami jako dane dostępne w czasie wykonywania powiązane z funkcjami, co pozwala na sprawdzenie typów. Przykład składni podpowiedzi typu:
def foo(i: int):return i
foo(5)
foo('oops')
W tym przypadku chcemy, aby wystąpił błąd, foo('oops')ponieważ typ argumentu z adnotacją to int. Dodana wskazówka typu nie powoduje wystąpienia błędu, gdy skrypt jest uruchamiany normalnie. Dodaje jednak atrybuty do funkcji opisującej oczekiwane typy, które inne programy mogą wyszukiwać i wykorzystywać do sprawdzania błędów typów.
Jednym z tych innych programów, za pomocą których można znaleźć błąd typu, jest mypy:
mypy script.py
script.py:12: error:Argument1 to "foo" has incompatible type "str"; expected "int"
(Może być konieczne zainstalowanie mypyz poziomu menedżera pakietów. Nie wydaje mi się, aby zawierał CPython, ale wydaje się, że ma pewien poziom „oficjalności”).
Sprawdzanie typów w ten sposób różni się od sprawdzania typów w statycznie skompilowanych językach kompilowanych. Ponieważ typy są dynamiczne w Pythonie, sprawdzanie typów musi być wykonywane w czasie wykonywania, co nakłada koszty - nawet na prawidłowe programy - jeśli nalegamy, aby zdarzyło się to przy każdej okazji. Jawne sprawdzanie typu może być również bardziej restrykcyjne niż to konieczne i powodować niepotrzebne błędy (np. Czy argument naprawdę musi być dokładnie tego samego listtypu, czy może wystarczy iterowalne powtórzenie?).
Zaletą jawnego sprawdzania typów jest to, że może wcześniej wychwytywać błędy i dawać wyraźniejsze komunikaty o błędach niż pisanie kaczych znaków. Dokładne wymagania dla typu kaczki można wyrazić tylko za pomocą dokumentacji zewnętrznej (mam nadzieję, że jest to dokładne i dokładne), a błędy z niekompatybilnych typów mogą wystąpić daleko od miejsca, z którego pochodzą.
Wskazówki dotyczące typów w Pythonie mają na celu zaoferowanie kompromisu, w którym typy można określać i sprawdzać, ale nie ma dodatkowych kosztów podczas zwykłego wykonywania kodu.
Te typingzmienne oferty Rodzaj opakowania, które mogą być stosowane w podpowiedzi typu zachowań potrzebnych do wyrażenia bez potrzeby poszczególnych rodzajów. Na przykład zawiera zmienne takie jak Iterablei Callablepodpowiedzi, aby określić potrzebę dowolnego typu z tymi zachowaniami.
Chociaż wskazówki dotyczące typów są najbardziej Pythońskim sposobem sprawdzania typów, często jeszcze bardziej Pythonic w ogóle nie sprawdza typów i polega na pisaniu kaczek. Podpowiedzi do czcionek są stosunkowo nowe, a jury jest nadal aktywne, gdy są najbardziej pythonicznym rozwiązaniem. Względnie niekontrowersyjne, ale bardzo ogólne porównanie: Podpowiedzi dotyczące typów zapewniają formę dokumentacji, którą można egzekwować, pozwalają na wcześniejsze generowanie kodu i łatwiejsze do zrozumienia błędy, mogą wychwycić błędy, których nie można wpisać podczas pisania kaczki, i można je sprawdzić statycznie (w nietypowy sposób sens, ale wciąż jest poza środowiskiem uruchomieniowym). Z drugiej strony, pisanie kaczką było od dawna sposobem Pythona, nie narzuca poznawczego pisania statycznego, jest mniej gadatliwe i akceptuje wszystkie możliwe typy, a potem niektóre.
-1: mypy określa się mianem „statycznego sprawdzania typu”, więc nie jestem pewien, skąd masz „sprawdzanie typu należy wykonać w czasie wykonywania”.
Kevin,
@Kevin Z perspektywy czasu była to niepotrzebna dygresja, ale aby uzyskać więcej informacji, wskazówki typu Pythona są przekształcane w dane środowiska wykonawczego i mypysą modułem Pythona używającym importlibdostępu do tych danych. To, czy jest to „statyczne sprawdzanie typu”, jest filozoficznym pytaniem, ale różni się od tego, czego większość by się spodziewała, ponieważ zaangażowany jest zwykły tłumacz języka i maszyny importujące.
Praxeolitic
4
To też nie jest prawda. To używa typed_ast, który sam w sobie jest po prostu klonem ast z dodatkowych funkcji. ast nie importuje modułów; analizuje je w abstrakcyjne drzewo składniowe.
Kevin,
18
Oto przykład, dlaczego pisanie kaczek jest złe, nie wiedząc, kiedy jest niebezpieczne. Na przykład: Oto kod Pythona (być może pomijający właściwe wcięcia), zauważ, że takiej sytuacji można uniknąć, zajmując się funkcjami isinstance i issclassof, aby upewnić się, że kiedy naprawdę potrzebujesz kaczki, nie dostaniesz bomby.
classBomb:def __init__(self):""def talk(self):
self.explode()def explode(self):print"BOOM!, The bomb explodes."classDuck:def __init__(self):""def talk(self):print"I am a duck, I will not blow up if you ask me to talk."classKid:
kids_duck =Nonedef __init__(self):print"Kid comes around a corner and asks you for money so he could buy a duck."def takeDuck(self, duck):
self.kids_duck = duck
print"The kid accepts the duck, and happily skips along"def doYourThing(self):print"The kid tries to get the duck to talk"
self.kids_duck.talk()
myKid =Kid()
myBomb =Bomb()
myKid.takeDuck(myBomb)
myKid.doYourThing()
Nawet przy sprawdzaniu typu można utworzyć class EvilDuck(Duck)i zastąpić talk (). Lub bardziej prawdopodobne, class ChineseCancerDuck(Duck)z nieprzyjemnym efektem ubocznym, który pojawia się dopiero po latach. Lepiej byłoby po prostu nadzorować swoje dziecko (i dokładnie testować jej zabawki :)
Brett Thomas,
36
Bomby nie mówią. Nie dodawaj nonsensownych metod, a to się nie stanie.
prawej
7
@Dmitry, to jest powszechna krytyka Duck Typing: en.wikipedia.org/wiki/Duck_typing#Criticism ... po prostu mówisz, że każdy interfejs, dla którego semantyka nie jest egzekwowana przez język, jest zły. Wierzę, że jest to bardziej podejście Java. Chodzi o to, że pisanie kaczek w Pythonie polega na tym, że działa tylko wtedy, gdy istnieje powszechnie stosowana konwencja o tym, co oznaczają określone interfejsy. Na przykład możesz pokorkować dużo kodu Pythona, zastępując __file__atrybut (zwykle używany do identyfikowania obiektów podobnych do plików) i oznaczający coś innego.
Dan Lenski
2
Wszystko sprowadza się do starego żartu: „Doktorze, boli mnie, kiedy to robię”. ... „Więc nie rób tego.”. Niezadowalające dla kogoś, kto jest przyzwyczajony do „jeśli się kompiluje, to działa”, ale właśnie dlatego testowanie obsesji wyrosło z dynamicznego świata językowego.
clacke
1
@clacke w zasadzie wymuszanie typów w środowisku wykonawczym jest zbyt drogie, ponieważ WSZYSTKO musi być obiektem (aby możliwe było odwzorowanie łańcucha na dowolny możliwy typ), i zbyt wygodne, aby nie robić uników, ponieważ unikanie pozwala na naprawdę potężne techniki prototypowania, które pokonują rzeczy, które są zwykle bardzo trudne do wykonania ze sztywnymi interfejsami. Poza tym każdy język statyczny stoi w obliczu punktu, w którym musi tworzyć pisanie kaczek za pomocą dynamicznych bibliotek, oceny i strunizacji lub interfejsów, a te rzeczy z natury nie powodują, że jest zły, a jedynie bardzo potężny.
Chociaż ten link może odpowiedzieć na pytanie, lepiej dołączyć tutaj istotne części odpowiedzi i podać link w celach informacyjnych. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie.
EKons,
7
Myślę, że fajną rzeczą w używaniu dynamicznego języka takiego jak Python jest to, że naprawdę nie powinieneś sprawdzać czegoś takiego.
Po prostu wywołałbym wymagane metody na twoim obiekcie i złapał AttributeError. Później pozwoli ci to wywoływać swoje metody z innymi (pozornie niezwiązanymi) obiektami w celu wykonania różnych zadań, takich jak wyśmiewanie obiektu do testowania.
Używałem tego bardzo często podczas pobierania danych z Internetu, za pomocą urllib2.urlopen()których zwracany jest obiekt typu plik . To z kolei można przekazać do prawie każdej metody, która czyta z pliku, ponieważ implementuje tę samą read()metodę, co prawdziwy plik.
Ale jestem pewien, że jest czas i miejsce do korzystania isinstance(), w przeciwnym razie prawdopodobnie nie byłoby tam :)
Dzięki, to jest tajny kod, którego chciałem, gdy wyświetlałem go jako informację zwrotną dla użytkownika. Zajęło mi to zbyt długo, aby to znaleźć ...
Aaron D. Marasco
5
Do Hugo:
Prawdopodobnie masz na myśli listraczej niż array, ale wskazuje to na cały problem ze sprawdzaniem typu - nie chcesz wiedzieć, czy przedmiotowy obiekt jest listą, chcesz wiedzieć, czy jest to jakaś sekwencja, czy pojedynczy obiekt. Spróbuj więc użyć go jak sekwencji.
Powiedz, że chcesz dodać obiekt do istniejącej sekwencji lub jeśli jest to sekwencja obiektów, dodaj je wszystkie
Jedna sztuczka polega na tym, jeśli pracujesz z ciągami i / lub sekwencjami ciągów - to podchwytliwe, ponieważ ciąg jest często uważany za pojedynczy obiekt, ale jest to również ciąg znaków. Gorzej, ponieważ tak naprawdę jest to ciąg ciągów o jednej długości.
Zwykle wybieram takie zaprojektowanie interfejsu API, aby akceptował tylko jedną wartość lub sekwencję - to ułatwia. W [ ]razie potrzeby nie jest trudno obliczyć wartość pojedynczą, gdy ją przekażesz.
(Chociaż może to powodować błędy w łańcuchach, ponieważ wyglądają jak (są) sekwencjami.)
Odpowiedzi:
Aby sprawdzić, czy
o
jest instancjąstr
lub jakąkolwiek podklasąstr
, użyj isinstance (byłby to sposób „kanoniczny”):Aby sprawdzić, czy typ
o
jest dokładniestr
(wyklucz podklasy):Następujące działania również działają i mogą być przydatne w niektórych przypadkach:
Zobacz funkcje wbudowane w Python Library Reference istotnych informacji.
Jeszcze jedna uwaga: w tym przypadku, jeśli używasz Python 2, możesz chcieć użyć:
ponieważ będzie to również złapać ciągi Unicode (
unicode
nie jest podklasąstr
; obastr
iunicode
są podklasybasestring
). Zauważ, żebasestring
nie istnieje już w Pythonie 3, gdzie istnieje ścisłe oddzielenie ciągów (str
) i danych binarnych (bytes
).Alternatywnie,
isinstance
akceptuje krotkę klas. Zwróci to,True
jeślio
jest instancją dowolnej podklasy dowolnej z(str, unicode)
:źródło
type(a) is Object
to nie jest prawdą, że takisinstance(a, Object)
. Jeśli jednaktype(a) is SubClassOfObject
totype(a) is Object == False
, aleisinstance(a, Object) == True
. Dobrze?a is b
oznacza, że aib są dokładnie tym samym, tzn. odniesienia do tego samego bytu w pamięci. Więca
ib
musiałaby być dokładnie taka sama klasa, a nie podklasy, jak w przypadkuisinstance()
. Zobacz na przykład stackoverflow.com/a/133024/1072212Najbardziej pythonowy sposób sprawdzić typ obiektu jest ... nie to sprawdzić.
Ponieważ Python zachęca do pisania kaczego , powinieneś po prostu
try...except
używać metod obiektu tak, jak chcesz. Więc jeśli twoja funkcja szuka zapisywalnego obiektu pliku, nie sprawdzaj, czy jest to podklasafile
, po prostu spróbuj użyć jego.write()
metody!Oczywiście czasami te ładne abstrakcje rozpadają się i
isinstance(obj, cls)
są tym, czego potrzebujesz. Ale używaj oszczędnie.źródło
if hasattr(ob, "write") and callable(ob.write):
lub zapisać dostęp dofunc = getattr(ob, "write", None)
if callable(func): ...
hasattr
tylko błąd AttributeError - patrz: docs.python.org/3.4/library/functions.html#hasattrisinstance(o, str)
zwróci,True
jeślio
jeststr
lub jest typu, który dziedziczystr
.type(o) is str
wróci,True
jeśli i tylko jeślio
jest str. Zwróci,False
jeślio
jest typu, który dziedziczystr
.źródło
isinstance
itype(var) == type('')
nie jest wyraźna.Po zadaniu pytania i udzieleniu odpowiedzi do Pythona dodano wskazówki typu . Wskazówki dotyczące typów w Pythonie umożliwiają sprawdzanie typów, ale w zupełnie inny sposób niż w przypadku języków typowanych statycznie. Wskazówki dotyczące typów w Pythonie kojarzą oczekiwane typy argumentów z funkcjami jako dane dostępne w czasie wykonywania powiązane z funkcjami, co pozwala na sprawdzenie typów. Przykład składni podpowiedzi typu:
W tym przypadku chcemy, aby wystąpił błąd,
foo('oops')
ponieważ typ argumentu z adnotacją toint
. Dodana wskazówka typu nie powoduje wystąpienia błędu, gdy skrypt jest uruchamiany normalnie. Dodaje jednak atrybuty do funkcji opisującej oczekiwane typy, które inne programy mogą wyszukiwać i wykorzystywać do sprawdzania błędów typów.Jednym z tych innych programów, za pomocą których można znaleźć błąd typu, jest
mypy
:(Może być konieczne zainstalowanie
mypy
z poziomu menedżera pakietów. Nie wydaje mi się, aby zawierał CPython, ale wydaje się, że ma pewien poziom „oficjalności”).Sprawdzanie typów w ten sposób różni się od sprawdzania typów w statycznie skompilowanych językach kompilowanych. Ponieważ typy są dynamiczne w Pythonie, sprawdzanie typów musi być wykonywane w czasie wykonywania, co nakłada koszty - nawet na prawidłowe programy - jeśli nalegamy, aby zdarzyło się to przy każdej okazji. Jawne sprawdzanie typu może być również bardziej restrykcyjne niż to konieczne i powodować niepotrzebne błędy (np. Czy argument naprawdę musi być dokładnie tego samego
list
typu, czy może wystarczy iterowalne powtórzenie?).Zaletą jawnego sprawdzania typów jest to, że może wcześniej wychwytywać błędy i dawać wyraźniejsze komunikaty o błędach niż pisanie kaczych znaków. Dokładne wymagania dla typu kaczki można wyrazić tylko za pomocą dokumentacji zewnętrznej (mam nadzieję, że jest to dokładne i dokładne), a błędy z niekompatybilnych typów mogą wystąpić daleko od miejsca, z którego pochodzą.
Wskazówki dotyczące typów w Pythonie mają na celu zaoferowanie kompromisu, w którym typy można określać i sprawdzać, ale nie ma dodatkowych kosztów podczas zwykłego wykonywania kodu.
Te
typing
zmienne oferty Rodzaj opakowania, które mogą być stosowane w podpowiedzi typu zachowań potrzebnych do wyrażenia bez potrzeby poszczególnych rodzajów. Na przykład zawiera zmienne takie jakIterable
iCallable
podpowiedzi, aby określić potrzebę dowolnego typu z tymi zachowaniami.Chociaż wskazówki dotyczące typów są najbardziej Pythońskim sposobem sprawdzania typów, często jeszcze bardziej Pythonic w ogóle nie sprawdza typów i polega na pisaniu kaczek. Podpowiedzi do czcionek są stosunkowo nowe, a jury jest nadal aktywne, gdy są najbardziej pythonicznym rozwiązaniem. Względnie niekontrowersyjne, ale bardzo ogólne porównanie: Podpowiedzi dotyczące typów zapewniają formę dokumentacji, którą można egzekwować, pozwalają na wcześniejsze generowanie kodu i łatwiejsze do zrozumienia błędy, mogą wychwycić błędy, których nie można wpisać podczas pisania kaczki, i można je sprawdzić statycznie (w nietypowy sposób sens, ale wciąż jest poza środowiskiem uruchomieniowym). Z drugiej strony, pisanie kaczką było od dawna sposobem Pythona, nie narzuca poznawczego pisania statycznego, jest mniej gadatliwe i akceptuje wszystkie możliwe typy, a potem niektóre.
źródło
mypy
są modułem Pythona używającymimportlib
dostępu do tych danych. To, czy jest to „statyczne sprawdzanie typu”, jest filozoficznym pytaniem, ale różni się od tego, czego większość by się spodziewała, ponieważ zaangażowany jest zwykły tłumacz języka i maszyny importujące.Oto przykład, dlaczego pisanie kaczek jest złe, nie wiedząc, kiedy jest niebezpieczne. Na przykład: Oto kod Pythona (być może pomijający właściwe wcięcia), zauważ, że takiej sytuacji można uniknąć, zajmując się funkcjami isinstance i issclassof, aby upewnić się, że kiedy naprawdę potrzebujesz kaczki, nie dostaniesz bomby.
źródło
class EvilDuck(Duck)
i zastąpić talk (). Lub bardziej prawdopodobne,class ChineseCancerDuck(Duck)
z nieprzyjemnym efektem ubocznym, który pojawia się dopiero po latach. Lepiej byłoby po prostu nadzorować swoje dziecko (i dokładnie testować jej zabawki :)__file__
atrybut (zwykle używany do identyfikowania obiektów podobnych do plików) i oznaczający coś innego.Link do dokumentów
źródło
Myślę, że fajną rzeczą w używaniu dynamicznego języka takiego jak Python jest to, że naprawdę nie powinieneś sprawdzać czegoś takiego.
Po prostu wywołałbym wymagane metody na twoim obiekcie i złapał
AttributeError
. Później pozwoli ci to wywoływać swoje metody z innymi (pozornie niezwiązanymi) obiektami w celu wykonania różnych zadań, takich jak wyśmiewanie obiektu do testowania.Używałem tego bardzo często podczas pobierania danych z Internetu, za pomocą
urllib2.urlopen()
których zwracany jest obiekt typu plik . To z kolei można przekazać do prawie każdej metody, która czyta z pliku, ponieważ implementuje tę samąread()
metodę, co prawdziwy plik.Ale jestem pewien, że jest czas i miejsce do korzystania
isinstance()
, w przeciwnym razie prawdopodobnie nie byłoby tam :)źródło
W przypadku bardziej złożonych walidacji typów podoba mi się podejście walidatora typeguard oparte na adnotacjach typu python:
Możesz przeprowadzać bardzo złożone weryfikacje w bardzo czysty i czytelny sposób.
źródło
Możesz sprawdzić typ zmiennej, używając __name__ typu.
Dawny:
źródło
Do Hugo:
Prawdopodobnie masz na myśli
list
raczej niżarray
, ale wskazuje to na cały problem ze sprawdzaniem typu - nie chcesz wiedzieć, czy przedmiotowy obiekt jest listą, chcesz wiedzieć, czy jest to jakaś sekwencja, czy pojedynczy obiekt. Spróbuj więc użyć go jak sekwencji.Powiedz, że chcesz dodać obiekt do istniejącej sekwencji lub jeśli jest to sekwencja obiektów, dodaj je wszystkie
Jedna sztuczka polega na tym, jeśli pracujesz z ciągami i / lub sekwencjami ciągów - to podchwytliwe, ponieważ ciąg jest często uważany za pojedynczy obiekt, ale jest to również ciąg znaków. Gorzej, ponieważ tak naprawdę jest to ciąg ciągów o jednej długości.
Zwykle wybieram takie zaprojektowanie interfejsu API, aby akceptował tylko jedną wartość lub sekwencję - to ułatwia. W
[ ]
razie potrzeby nie jest trudno obliczyć wartość pojedynczą, gdy ją przekażesz.(Chociaż może to powodować błędy w łańcuchach, ponieważ wyglądają jak (są) sekwencjami.)
źródło
Prostym sposobem sprawdzenia typu jest porównanie go z czymś, kogo znasz.
źródło
Myślę, że najlepszym sposobem jest dobre wpisanie zmiennych. Możesz to zrobić, korzystając z biblioteki „pisania”.
Przykład:
from typing import NewType UserId = NewType ('UserId', int) some_id = UserId (524313
) `Zobacz https://docs.python.org/3/library/typing.html
źródło
Możesz sprawdzić w poniższym wierszu, aby sprawdzić, jaki typ znaku jest podana wartość:
źródło