Powiedziałbym, że zdecydowanie powinieneś przeczytać odnośnik, do którego się odwołujesz, który podaje wiele szczegółów, dlaczego sprawdzanie typu obiektu jest zwykle złym pomysłem i co prawdopodobnie powinieneś zrobić zamiast tego.
Jeff Shannon
2
powinieneś użyć basestr, a nie str. w przeciwnym razie nie wybierzesz Unicode. (chociaż dla 3.x myślę, że str jest basestrem)
hasen
36
isinstance Pracuje:
if isinstance(obj,MyClass): do_foo(obj)
ale pamiętaj: jeśli wygląda jak kaczka, a jeśli brzmi jak kaczka, to jest to kaczka.
EDYCJA: W przypadku typu Brak możesz po prostu wykonać:
def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True) Zwraca „1” zamiast „Nie”. Jak to obejść?
dig_123
Jeśli chcesz użyć isinstanceale sprawdź również dla Noneówczesnych isinstance(obj, (MyClass, type(None)))dzieł. types.NoneTypezostał usunięty z Pythona 3, więc nie jest tak przenośny, jak type(None)uzyskanie odniesienia do NoneType.
Santeri Paavolainen
33
Po pierwsze, unikaj wszelkich porównań typów. Są bardzo, bardzo rzadko potrzebne. Czasami pomagają sprawdzić typy parametrów w funkcji - nawet to rzadkie. Dane nieprawidłowego typu spowodują wyjątek, a to wszystko, czego kiedykolwiek będziesz potrzebować.
Wszystkie podstawowe funkcje konwersji będą mapowane jako równe funkcji typu.
type(9)is int
type(2.5)is float
type('x')is str
type(u'x')is unicode
type(2+3j)is complex
Żaden, BTW, nigdy nie wymaga tego rodzaju kontroli. None jest jedynym wystąpieniem NoneType. Obiekt None jest singletonem. Po prostu zaznacz opcję Brak
variable isNone
Przy okazji, nie używaj powyższego ogólnie. Użyj zwykłych wyjątków i własnego naturalnego polimorfizmu Pythona.
Jeśli sprawdzasz poprawność danych wejściowych z DSL, potrzebujesz tego wszystkiego NoneType. Co jeśli parametr może być str, unicodealbo None? isinstance(x, (str, unicode, types.NoneType))jest znacznie czystszy niż sprawdzanie None. Jeśli tworzysz narzędzia do odroczonych obliczeń lub jeśli masz zamiar uruchomić długi lub wymagający dużej ilości zasobów proces, warto wychwycić typebłędy z wyprzedzeniem, podczas niestandardowego kroku weryfikacji. To była kluczowa część prawie każdego naukowego projektu komputerowego, nad którym kiedykolwiek pracowałem. Ze wszystkich projektów deweloperskich, jakie widziałem, więcej tego potrzebowało niż nie.
>>>import types>>> x ="mystring">>> isinstance(x, types.StringType)True>>> x =5>>> isinstance(x, types.IntType)True>>> x =None>>> isinstance(x, types.NoneType)True
Zawsze możesz użyć type(x) == type(y)sztuczki, gdzie yjest coś o znanym typie.
# check if x is a regular string
type(x)== type('')# check if x is an integer
type(x)== type(1)# check if x is a NoneType
type(x)== type(None)
Często istnieją lepsze sposoby na zrobienie tego, szczególnie w przypadku dowolnego nowego Pythona. Ale jeśli chcesz zapamiętać tylko jedną rzecz, możesz to zapamiętać.
W takim przypadku lepszym sposobem byłoby:
# check if x is a regular string
type(x)== str# check if x is either a regular string or a unicode string
type(x)in[str, unicode]# alternatively:
isinstance(x, basestring)# check if x is an integer
type(x)== int# check if x is a NoneType
x isNone
Zwróć uwagę na ostatni przypadek: NoneTypew pythonie jest tylko jedno wystąpienie None. Zobaczysz NoneType w wyjątkach ( TypeError: 'NoneType' object is unsubscriptable- zdarza mi się cały czas ...), ale prawie nigdy nie będziesz musiał odnosić się do tego w kodzie.
Wreszcie, jak zauważa fengshaun, sprawdzanie typów w Pythonie nie zawsze jest dobrym pomysłem. Bardziej pythonowe jest po prostu użycie wartości tak, jakby była to oczekiwany typ i wyłapywanie (lub pozwolenie na propagację) wyjątków, które z niej wynikają.
Warto wiedzieć, że isinstance () jest preferowanym sposobem sprawdzania typów w Pythonie (kiedy trzeba to zrobić).
David Z
6
Jesteś już blisko! stringjest modułem, a nie typem. Prawdopodobnie chcesz porównać typ z objobiektem typu dla ciągów, a mianowicie str:
type(obj)== str # this works because str is already a type
Alternatywnie:
type(obj)== type('')
Uwaga, w Pythonie 2, jeśli objjest to typ Unicode, żadne z powyższych nie będzie działać. Ani nie będzie isinstance(). Zobacz komentarze Johna do tego posta, aby dowiedzieć się, jak to obejść ... Próbowałem to sobie przypomnieć od około 10 minut, ale miałem blok pamięci!
Użyj basestring z isinstance (), aby uzyskać zarówno str, jak i unicode.
John Fouhy
5
To dlatego, że musisz pisać
s="hello"
type(s)== type("")
type akceptuje instancję i zwraca jej typ. W takim przypadku musisz porównać typy dwóch instancji.
Jeśli chcesz przeprowadzić sprawdzanie zapobiegawcze, lepiej jest sprawdzić obsługiwany interfejs niż typ.
Typ tak naprawdę nie mówi ci wiele, poza tym, że twój kod potrzebuje instancji określonego typu, niezależnie od tego, że możesz mieć inną instancję zupełnie innego typu, co byłoby całkowicie w porządku, ponieważ implementuje ten sam interfejs .
Na przykład załóżmy, że masz ten kod
def firstElement(parameter):return parameter[0]
Teraz przypuśćmy, że powiesz: chcę, aby ten kod akceptował tylko krotkę.
import typesdef firstElement(parameter):if type(parameter)!= types.TupleType:raiseTypeError("function accepts only a tuple")return parameter[0]
Zmniejsza to możliwość ponownego wykorzystania tej procedury. Nie zadziała, jeśli przekażesz listę, ciąg znaków lub numpy.array. Coś lepszego byłoby
ale nie ma sensu to robić: parametr [0] zgłosi wyjątek, jeśli protokół i tak nie jest spełniony ... to oczywiście, chyba że chcesz zapobiec efektom ubocznym lub musisz odzyskać kontrolę po wywołaniach, które możesz wywołać przed niepowodzeniem. (Głupi) przykład, żeby podkreślić:
w tym przypadku twój kod zgłosi wyjątek przed uruchomieniem wywołania system (). Bez sprawdzenia interfejsu usunąłbyś plik, a następnie zgłosił wyjątek.
Dziękujemy za wskazanie faktycznego preferowanego sposobu sprawdzania interfejsów. Wiele odpowiedzi tutaj o tym wspomina, ale niewiele z nich podaje przykłady tego, co jest dobre. Nadal nie odpowiada bezpośrednio na moje osobiste pytanie (próbuję oddzielić listę ciągów zawierających wiele znaczących elementów od ciągu zawierającego wiele nieistotnych elementów. Dzięki!
Nick
5
Użyj str zamiast string
type ( obj )== str
Wyjaśnienie
>>> a ="Hello">>> type(a)==str
True>>> type(a)<type 'str'>>>>
co? dlaczego jest to ogólnie zły pomysł? To zły pomysł tylko w przypadku stringów (w wersjach wcześniejszych niż 3.0), ponieważ istnieją dwa typy łańcuchów, str i unicode. W przypadku tablic imho to dobry pomysł.
hasen
@hasen: to ogólnie zły pomysł. Co się stanie, jeśli zdefiniuję własny typ, który zachowuje się jak tablica, ale, powiedzmy, pobiera wartości z bazy danych? Twój kod zawiedzie z moim typem bez powodu.
Cóż, cały powód (przynajmniej dla mnie) przy sprawdzaniu typu jest dokładnie taki, że chcę radzić sobie z tablicami inaczej niż inne typy (w tym typy imitujące tablice).
hasen
2
Jesteś w błędzie. Podam konkretny przykład: django ma skrót do renderowania szablonu, który może akceptować ciąg znaków lub tablicę ciągów. Teraz zarówno łańcuchy, jak i tablice (listy) są iterowalne, ale w tym przypadku funkcje muszą je rozróżniać.
Aby uzyskać typ, użyj elementu __class__członkowskiego, jak wunknown_thing.__class__
Mówienie o pisaniu na klawiaturze jest tu bezużyteczne, ponieważ nie odpowiada na całkiem dobre pytanie. W moim kodzie aplikacji nigdy nie muszę znać typu czegoś, ale wciąż przydatna jest możliwość nauczenia się typu obiektu. Czasami potrzebuję uzyskać rzeczywistą klasę, aby zweryfikować test jednostkowy. Duck typing staje na przeszkodzie, ponieważ wszystkie możliwe obiekty mają to samo API, ale tylko jeden jest poprawny. Poza tym czasami zajmuję się cudzym kodem i nie mam pojęcia, jaki obiekt został mi przekazany. To jest mój największy problem z dynamicznie wpisywanymi językami, takimi jak Python. Wersja 1 jest bardzo łatwa i szybka w opracowaniu. Wersja 2 jest uciążliwa, zwłaszcza jeśli nie napisałeś wersji 1. Więc czasami, gdy pracuję z funkcją, której nie napisałem, muszę znać typ parametru,
Tutaj __class__przydaje się parametr. To (o ile wiem) najlepszy sposób (może jedyny) na uzyskanie typu obiektu.
Użyj isinstance(object, type). Jak wyżej, jest to łatwe w użyciu, jeśli znasz poprawną type, np.
isinstance('dog', str)## gives bool True
Ale w przypadku bardziej ezoterycznych obiektów może to być trudne w użyciu. Na przykład:
import numpy as np
a = np.array([1,2,3])
isinstance(a,np.array)## breaks
ale możesz zrobić tę sztuczkę:
y = type(np.array([1]))
isinstance(a,y)## gives bool True
Dlatego zalecam utworzenie instancji zmiennej ( yw tym przypadku) z typem obiektu, który chcesz sprawdzić (np. type(np.array())), A następnie użycie isinstance.
type(obj) == str
Odpowiedzi:
W twoim przypadku
isinstance("this is a string", str)
wróciTrue
.Możesz również przeczytać to: http://www.canonical.org/~kragen/isinstance/
źródło
isinstance
Pracuje:ale pamiętaj: jeśli wygląda jak kaczka, a jeśli brzmi jak kaczka, to jest to kaczka.
EDYCJA: W przypadku typu Brak możesz po prostu wykonać:
źródło
def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True)
Zwraca „1” zamiast „Nie”. Jak to obejść?isinstance
ale sprawdź również dlaNone
ówczesnychisinstance(obj, (MyClass, type(None)))
dzieł.types.NoneType
został usunięty z Pythona 3, więc nie jest tak przenośny, jaktype(None)
uzyskanie odniesienia doNoneType
.Po pierwsze, unikaj wszelkich porównań typów. Są bardzo, bardzo rzadko potrzebne. Czasami pomagają sprawdzić typy parametrów w funkcji - nawet to rzadkie. Dane nieprawidłowego typu spowodują wyjątek, a to wszystko, czego kiedykolwiek będziesz potrzebować.
Wszystkie podstawowe funkcje konwersji będą mapowane jako równe funkcji typu.
Jest kilka innych przypadków.
Żaden, BTW, nigdy nie wymaga tego rodzaju kontroli. None jest jedynym wystąpieniem NoneType. Obiekt None jest singletonem. Po prostu zaznacz opcję Brak
Przy okazji, nie używaj powyższego ogólnie. Użyj zwykłych wyjątków i własnego naturalnego polimorfizmu Pythona.
źródło
NoneType
. Co jeśli parametr może byćstr
,unicode
alboNone
?isinstance(x, (str, unicode, types.NoneType))
jest znacznie czystszy niż sprawdzanieNone
. Jeśli tworzysz narzędzia do odroczonych obliczeń lub jeśli masz zamiar uruchomić długi lub wymagający dużej ilości zasobów proces, warto wychwycićtype
błędy z wyprzedzeniem, podczas niestandardowego kroku weryfikacji. To była kluczowa część prawie każdego naukowego projektu komputerowego, nad którym kiedykolwiek pracowałem. Ze wszystkich projektów deweloperskich, jakie widziałem, więcej tego potrzebowało niż nie.W przypadku innych typów sprawdź moduł typów :
PS Typechecking to zły pomysł.
źródło
Zawsze możesz użyć
type(x) == type(y)
sztuczki, gdziey
jest coś o znanym typie.Często istnieją lepsze sposoby na zrobienie tego, szczególnie w przypadku dowolnego nowego Pythona. Ale jeśli chcesz zapamiętać tylko jedną rzecz, możesz to zapamiętać.
W takim przypadku lepszym sposobem byłoby:
Zwróć uwagę na ostatni przypadek:
NoneType
w pythonie jest tylko jedno wystąpienieNone
. Zobaczysz NoneType w wyjątkach (TypeError: 'NoneType' object is unsubscriptable
- zdarza mi się cały czas ...), ale prawie nigdy nie będziesz musiał odnosić się do tego w kodzie.Wreszcie, jak zauważa fengshaun, sprawdzanie typów w Pythonie nie zawsze jest dobrym pomysłem. Bardziej pythonowe jest po prostu użycie wartości tak, jakby była to oczekiwany typ i wyłapywanie (lub pozwolenie na propagację) wyjątków, które z niej wynikają.
źródło
Jesteś już blisko!
string
jest modułem, a nie typem. Prawdopodobnie chcesz porównać typ zobj
obiektem typu dla ciągów, a mianowiciestr
:Alternatywnie:
Uwaga, w Pythonie 2, jeśli
obj
jest to typ Unicode, żadne z powyższych nie będzie działać. Ani nie będzieisinstance()
. Zobacz komentarze Johna do tego posta, aby dowiedzieć się, jak to obejść ... Próbowałem to sobie przypomnieć od około 10 minut, ale miałem blok pamięci!źródło
To dlatego, że musisz pisać
type akceptuje instancję i zwraca jej typ. W takim przypadku musisz porównać typy dwóch instancji.
Jeśli chcesz przeprowadzić sprawdzanie zapobiegawcze, lepiej jest sprawdzić obsługiwany interfejs niż typ.
Typ tak naprawdę nie mówi ci wiele, poza tym, że twój kod potrzebuje instancji określonego typu, niezależnie od tego, że możesz mieć inną instancję zupełnie innego typu, co byłoby całkowicie w porządku, ponieważ implementuje ten sam interfejs .
Na przykład załóżmy, że masz ten kod
Teraz przypuśćmy, że powiesz: chcę, aby ten kod akceptował tylko krotkę.
Zmniejsza to możliwość ponownego wykorzystania tej procedury. Nie zadziała, jeśli przekażesz listę, ciąg znaków lub numpy.array. Coś lepszego byłoby
ale nie ma sensu to robić: parametr [0] zgłosi wyjątek, jeśli protokół i tak nie jest spełniony ... to oczywiście, chyba że chcesz zapobiec efektom ubocznym lub musisz odzyskać kontrolę po wywołaniach, które możesz wywołać przed niepowodzeniem. (Głupi) przykład, żeby podkreślić:
w tym przypadku twój kod zgłosi wyjątek przed uruchomieniem wywołania system (). Bez sprawdzenia interfejsu usunąłbyś plik, a następnie zgłosił wyjątek.
źródło
Użyj str zamiast string
Wyjaśnienie
źródło
używam
type(x) == type(y)
Na przykład, jeśli chcę sprawdzić, czy coś jest tablicą:
sprawdzenie ciągów:
Jeśli chcesz sprawdzić, czy nie ma wartości None, użyj is
źródło
myślę, że to powinno wystarczyć
źródło
Typ nie działa na niektórych klasach. Jeśli nie masz pewności co do typu obiektu, skorzystaj z
__class__
metody:Zobacz także ten artykuł - http://www.siafoo.net/article/56
źródło
Aby uzyskać typ, użyj elementu
__class__
członkowskiego, jak wunknown_thing.__class__
Mówienie o pisaniu na klawiaturze jest tu bezużyteczne, ponieważ nie odpowiada na całkiem dobre pytanie. W moim kodzie aplikacji nigdy nie muszę znać typu czegoś, ale wciąż przydatna jest możliwość nauczenia się typu obiektu. Czasami potrzebuję uzyskać rzeczywistą klasę, aby zweryfikować test jednostkowy. Duck typing staje na przeszkodzie, ponieważ wszystkie możliwe obiekty mają to samo API, ale tylko jeden jest poprawny. Poza tym czasami zajmuję się cudzym kodem i nie mam pojęcia, jaki obiekt został mi przekazany. To jest mój największy problem z dynamicznie wpisywanymi językami, takimi jak Python. Wersja 1 jest bardzo łatwa i szybka w opracowaniu. Wersja 2 jest uciążliwa, zwłaszcza jeśli nie napisałeś wersji 1. Więc czasami, gdy pracuję z funkcją, której nie napisałem, muszę znać typ parametru,
Tutaj
__class__
przydaje się parametr. To (o ile wiem) najlepszy sposób (może jedyny) na uzyskanie typu obiektu.źródło
Użyj
isinstance(object, type)
. Jak wyżej, jest to łatwe w użyciu, jeśli znasz poprawnątype
, np.Ale w przypadku bardziej ezoterycznych obiektów może to być trudne w użyciu. Na przykład:
ale możesz zrobić tę sztuczkę:
Dlatego zalecam utworzenie instancji zmiennej (
y
w tym przypadku) z typem obiektu, który chcesz sprawdzić (np.type(np.array())
), A następnie użycieisinstance
.źródło
Możesz porównać klasy, aby sprawdzić poziom.
źródło