Jak sprawdzić, czy typ zmiennej jest łańcuchem?

766

Czy istnieje sposób sprawdzenia, czy typ zmiennej w pythonie to string:

isinstance(x,int);

dla wartości całkowitych?

c_pleaseUpvote
źródło
11
Wymagana lektura na isinstance, jeśli uczysz się python canonical.org/~kragen/isinstance .
whaley 30.01.11
Uważaj na ints od tego czasu isinstance(True, int) is True.
Albert Tugushev
isinstance(x,str)jest poprawny w Pythonie 3 (str jest typem podstawowym).
MasterControlProgram

Odpowiedzi:

1137

W Python 2.x zrobiłbyś to

isinstance(s, basestring)

basestringJest to streszczenie nadklasą z stri unicode. Można go użyć do sprawdzenia, czy obiekt jest instancją strlub unicode.


W Pythonie 3.x poprawnym testem jest

isinstance(s, str)

bytesKlasa nie jest uważany za typ string w Pythonie 3.

Sven Marnach
źródło
10
@Yarin: Nie. Ale to nie ma znaczenia, ponieważ Python 3.x wcale nie jest kompatybilny z Python 2.x.
netcoder
2
Stwierdziłem, że isinstance (s, str) działa z py27, przetestowany na: Python 2.7.5 (domyślnie, 25 sierpnia 2013, 00:04:04) [Kompatybilny z GCC 4.2.1 Apple LLVM 5.0 (clang-500.0.68)] na darwin.
kakyo
25
@kakyo: Problem polega na tym, że będzie brakować unicodeobiektów, które również należy traktować jako łańcuchy. Zarówno typ, jak stri typ unicodemają wspólną klasę podstawową basestringi właśnie tego chcesz sprawdzić.
Sven Marnach
7
@Yarin, jeśli przenosisz coś z wersji 2.x na 3.x, zawsze możesz to przypisać basestring = str.
Jack
9
@AdamErickson Dla zgodności z czym dokładnie? Nie pomaga w kompatybilności z Python 3, ponieważ nie ma go unicodew Pythonie 3. Moje zalecenie dotyczące zgodności między Pythonem 2 i 3 to korzystanie z biblioteki „six”. (Szczególnie isintance(s, six.string_types)w tym przypadku)
Sven Marnach
222

Wiem, że jest to stary temat, ale jako pierwszy pokazany w google i biorąc pod uwagę, że nie uważam żadnej z odpowiedzi za zadowalającą, zostawię to tutaj do wglądu w przyszłości:

six to biblioteka kompatybilności z Python 2 i 3, która już obejmuje ten problem. Następnie możesz zrobić coś takiego:

import six

if isinstance(value, six.string_types):
    pass # It's a string !!

Sprawdzając kod, oto, co znajdziesz:

import sys

PY3 = sys.version_info[0] == 3

if PY3:
    string_types = str,
else:
    string_types = basestring,
André Fratelli
źródło
4
Np. Dla jednej linijki: value_is_string = isinstance(value, str if sys.version_info[0] >= 3 else basestring)gdzie >=zakłada się, że w końcu Python 4+ zachowuje strklasę root dla łańcuchów.
Pi Marillion,
63

W Python 3.x lub Python 2.7.6

if type(x) == str:
Texom512
źródło
10
Podoba mi się elegancja „if type (x) in (str, unicode):”, ale widzę, że PyLint zaznacza to jako „unidiomatic”.
eukras
15
Porównywanie typów z ==jest wyraźnie odradzane przez PEP8 i ma kilka wad, które należy uznać za „jednodiomatyczne”, np. Nie wykrywa instancji podklas str, które również należy traktować jako łańcuchy. Jeśli naprawdę chcesz sprawdzić dokładnie typ stri wyraźnie wykluczyć podklasy, użyj type(x) is str.
Sven Marnach,
17

możesz to zrobić:

var = 1
if type(var) == int:
   print('your variable is an integer')

lub:

var2 = 'this is variable #2'
if type(var2) == str:
    print('your variable is a string')
else:
    print('your variable IS NOT a string')

mam nadzieję że to pomoże!

F. Taylor
źródło
11

Edytuj na podstawie lepszej odpowiedzi poniżej. Zejdź w dół o 3 odpowiedzi i dowiedz się o chłodzie basestringu.

Stara odpowiedź: uważaj na ciągi znaków Unicode, które można uzyskać z kilku miejsc, w tym wszystkich wywołań COM w systemie Windows.

if isinstance(target, str) or isinstance(target, unicode):
Wade Hatler
źródło
1
Dobry chwyt Nie wiedziałem o bazowaniu. Wspomniano o 3 postach w dół i wydaje się lepszą odpowiedzią.
Wade Hatler,
6
isinstance()bierze również krotkę jako drugi argument. Więc nawet jeśli basestringnie istniał, możesz po prostu użyć isinstance(target, (str, unicode)).
Martijn Pieters
3
W Pythonie 3.5.1 unicodenie wydaje się być zdefiniowany:NameError: name 'unicode' is not defined
Eric Hu
11

ponieważ basestringnie jest zdefiniowany w Python3, ta mała sztuczka może pomóc w kompatybilności kodu:

try: # check whether python knows about 'basestring'
   basestring
except NameError: # no, it doesn't (it's Python3); use 'str' instead
   basestring=str

po tym możesz uruchomić następujący test na Python2 i Python3

isinstance(myvar, basestring)
umläute
źródło
4
Lub jeśli chcesz również złapać ciągi bajtów:basestring = (str, bytes)
Mark Ransom
10

Python 2/3 łącznie z Unicode

from __future__ import unicode_literals
from builtins import str  #  pip install future
isinstance('asdf', str)   #  True
isinstance(u'asdf', str)  #  True

http://python-future.org/overview.html

crizCraig
źródło
1
Wielkie dzięki! Istnieje wiele różnych odpowiedzi w Internecie, ale jedynym dobrym jest ten. Pierwsza linia sprawia, że type('foo')jest unicodedomyślnie w python 2, a druga marka strjest instancją unicode. To sprawia, że ​​kod jest poprawny w Pythonie 2 i 3. Jeszcze raz dziękuję!
Narann,
9

Chcę również zauważyć, że jeśli chcesz sprawdzić, czy typ zmiennej jest określonym rodzajem, możesz porównać typ zmiennej z typem znanego obiektu.

W przypadku ciągu możesz użyć tego

type(s) == type('')
Daniil Grankin
źródło
7
Jest to okropny, straszny sposób wpisywania sprawdzania w pythonie. Co jeśli odziedziczy inna klasa str? Co z ciągami znaków Unicode, które nawet nie dziedziczą strpo 2.x? Użyj isinstance(s, basestring)w 2.x lub isinstance(s, str)3.x.
Jack
1
@Jack, przeczytaj pytanie, a także zauważ, że nie piszę, że to najlepszy sposób, tylko inny sposób.
Daniil Grankin
9
Jest to zły pomysł z 3 powodów: isinstance()pozwala na podklasy (które są również łańcuchami, po prostu wyspecjalizowane), dodatkowe type('')wywołanie jest zbędne, gdy można po prostu użyć, stra typy są singletonami, więc type(s) is strbędzie to bardziej wydajny test.
Martijn Pieters
8

Wiele dobrych sugestii dostarczonych przez innych tutaj, ale nie widzę dobrego podsumowania dla wielu platform. Poniższe informacje powinny być dobrym rozwiązaniem dla każdego programu w języku Python:

def isstring(s):
    # if we use Python 3
    if (sys.version_info[0] >= 3):
        return isinstance(s, str)
    # we use Python 2
    return isinstance(s, basestring)

W tej funkcji używamy, isinstance(object, classinfo)aby sprawdzić, czy nasze dane wejściowe są strw Pythonie 3, czy basestringw Pythonie 2.

duanev
źródło
1
To prawdopodobnie pęknie w Pythonie 4, >=przynajmniej weź pod uwagę .
thakis
2
bądź czystszy, aby sprawdzić, czy występują sześć
typów
@daonb importujący cały moduł tylko w celu przeprowadzenia testu jednowierszowego to myślenie, które powoduje, że szalone drzewa zależności i poważne wzdęcia psują coś, co powinno być czymś krótkim i małym. To twój telefon, oczywiście, ale po prostu powiedz ...
duanev
@duanev, jeśli martwisz się kompatybilnością z Pythonem 2/3, lepiej jest użyć w projekcie sześciu. Sześć jest również jednym plikiem, więc drzewa zależności / wzdęcia nie są tutaj problemem.
MoxieBall
7

Alternatywny sposób dla Python 2, bez użycia ciągu bazowego:

isinstance(s, (str, unicode))

Ale nadal nie będzie działać w Pythonie 3, ponieważ unicodenie jest zdefiniowany (w Pythonie 3).

yprez
źródło
7

Więc,

Masz wiele opcji, aby sprawdzić, czy twoja zmienna jest ciągiem:

a = "my string"
type(a) == str # first 
a.__class__ == str # second
isinstance(a, str) # third
str(a) == a # forth
type(a) == type('') # fifth

To zamówienie jest celowe.

PatNowak
źródło
5
a = '1000' # also tested for 'abc100', 'a100bc', '100abc'

isinstance(a, str) or isinstance(a, unicode)

zwraca True

type(a) in [str, unicode]

zwraca True

be_good_do_good
źródło
W przypadku Python 2.7.12 musiałem usunąć cudzysłowy: wpisz (a) w [str, unicode]
Adam Erickson
4

Oto moja odpowiedź na obsługę zarówno Pythona 2, jak i Pythona 3 wraz z następującymi wymaganiami:

  • Zapisany w kodzie Py3 z minimalnym kodem zgodności Py2.
  • Usuń kod kompatybilności Py2 później bez zakłóceń. Tj. Chodzi tylko o usunięcie, bez modyfikacji kodu Py3.
  • Unikaj używania sixlub podobnego modułu zgodności, ponieważ mają tendencję do ukrywania tego, co próbuje się osiągnąć.
  • Przyszłość dla potencjalnego Py4.

import sys
PY2 = sys.version_info.major == 2

# Check if string (lenient for byte-strings on Py2):
isinstance('abc', basestring if PY2 else str)

# Check if strictly a string (unicode-string):
isinstance('abc', unicode if PY2 else str)

# Check if either string (unicode-string) or byte-string:
isinstance('abc', basestring if PY2 else (str, bytes))

# Check for byte-string (Py3 and Py2.7):
isinstance('abc', bytes)
Cas
źródło
1

Jeśli nie chcesz polegać na zewnętrznych bibliotekach, działa to zarówno w przypadku Python 2.7+, jak i Python 3 ( http://ideone.com/uB4Kdc ):

# your code goes here
s = ["test"];
#s = "test";
isString = False;

if(isinstance(s, str)):
    isString = True;
try:
    if(isinstance(s, basestring)):
        isString = True;
except NameError:
    pass;

if(isString):
    print("String");
else:
    print("Not String");
mPrinC
źródło
1

Można po prostu użyć isinstance funkcji, aby upewnić się, że dane wejściowe jest od formatu ciąg lub Unicode . Poniższe przykłady pomogą ci łatwo zrozumieć.

>>> isinstance('my string', str)
True
>>> isinstance(12, str)
False
>>> isinstance('my string', unicode)
False
>>> isinstance(u'my string',  unicode)
True
Hassan Mehmood
źródło
-3
s = '123'
issubclass(s.__class__, str)
vadim vaduxa
źródło
-6

Tak to robię:

if type(x) == type(str()):
Użytkownik
źródło
4
type(str())to bardzo okrągły sposób powiedzenia str. Typy są singletonami, więc type(x) is strsą bardziej wydajne. isinstance()należy użyć zamiast tego, chyba że masz bardzo dobre powody, aby zignorować podklasy str.
Martijn Pieters
jeśli typ (x) to str:
shaurya uppal
-7

Widziałem:

hasattr(s, 'endswith') 
szybki ząb
źródło
-13
>>> thing = 'foo'
>>> type(thing).__name__ == 'str' or type(thing).__name__ == 'unicode'
True
Richard Urban
źródło
2
W takim przypadku wolisz type(thing).__name__ == 'str'nad type(thing) == strlub isinstance(thing, str)? Również unicodenie istnieje w nowoczesnych wersjach Pythona.
vaultah