Jak mogę sprawdzić, czy obiekt Python jest łańcuchem (zwykłym lub Unicode)?
Jak mogę sprawdzić, czy obiekt Python jest łańcuchem (zwykłym lub Unicode)?
Odpowiedzi:
Aby sprawdzić, czy obiekt o
jest typem ciągu podklasy typu ciągu:
isinstance(o, basestring)
ponieważ oba str
i unicode
są podklasy basestring
.
Aby sprawdzić, czy typ o
jest dokładnie str
:
type(o) is str
Aby sprawdzić, czy o
jest instancją str
lub jakąkolwiek podklasą str
:
isinstance(o, str)
Powyższe działa również dla ciągów Unicode, jeśli zastąpisz str
je unicode
.
Jednak może nie być wcale konieczne wykonywanie jawnego sprawdzania typu. „Pisanie kaczką” może pasować do twoich potrzeb. Zobacz http://docs.python.org/glossary.html#term-duck-typing .
Zobacz także Jaki jest kanoniczny sposób sprawdzania typu w python?
basestring
w py2.
W Pythonie 3.x basestring
nie jest już dostępny, podobnie jak str
jedyny typ ciągu (z semantyką Pythona 2.x unicode
).
Zatem sprawdzenie w Pythonie 3.x to po prostu:
isinstance(obj_to_test, str)
Jest to zgodne z poprawką oficjalnego 2to3
narzędzia konwersji: konwersja basestring
do str
.
Jeśli chcesz sprawdzić bez względu na wersję Pythona (2.x vs. 3.x), użyj six
( PyPI ) i jego string_types
atrybutu:
import six
if isinstance(obj, six.string_types):
print('obj is a string!')
Wewnątrz six
(bardzo lekki moduł z jednym plikiem) po prostu robi to :
import sys
PY3 = sys.version_info[0] == 3
if PY3:
string_types = str
else:
string_types = basestring
future
( PyPI ), aby nawet zachować nazwę:from past.builtins import basestring
basestring
a potem wróć do str
. Np.def is_string(obj): try: return isinstance(obj, basestring) # python 2 except NameError: return isinstance(obj, str) # python 3
Znalazłem to i więcej pythonic
:
if type(aObject) is str:
#do your stuff here
pass
ponieważ są obiekty typu singleton, to można wykorzystać, aby wykonać porównanie obiektu do rodzaju str
isinstance(obj_to_test, str)
jest oczywiście przeznaczony do testowania typu, i ma tę zaletę, że stosuje tę samą procedurę, co w przypadku innych przypadków innych niż str.
Jeśli ktoś chce się trzymać z dala od wyraźnego typu sprawdzania (i tam są dobre powody, aby trzymać z dala od niego), prawdopodobnie najbezpieczniejsze części protokołu strun do wyboru jest:
str(maybe_string) == maybe_string
Nie będzie iterować przez iterowalny lub iterator, nie nazywa listy ciągów ciągiem i poprawnie wykrywa ciąg podobny do łańcucha.
Oczywiście są wady. Na przykład str(maybe_string)
może być ciężka kalkulacja. Jak często odpowiedź brzmi: to zależy .
EDYCJA: Jak wskazuje @Tcll w komentarzach, pytanie faktycznie dotyczy sposobu wykrywania zarówno ciągów znaków Unicode, jak i bajtowania. W Pythonie 2 ta odpowiedź nie powiedzie się, z wyjątkiem ciągów znaków Unicode zawierających znaki inne niż ASCII, a w Pythonie 3 wróci do wszystkich bajtów.False
b = b'test'; r = str(b) == b
gdzie b
przechowuje takie same dane jak, str(b)
ale (będąc obiektem bajtów) nie sprawdza się jako ciąg.
Aby sprawdzić, czy twoja zmienna jest czymś, co możesz zrobić:
s='Hello World'
if isinstance(s,str):
#do something here,
Wynik isistance da ci logiczną wartość True lub False, dzięki czemu będziesz mógł odpowiednio dostosować. Możesz sprawdzić oczekiwany akronim swojej wartości, początkowo używając: type (s) Zwróci to napis „str”, dzięki czemu możesz go użyć w funkcji isistance.
Mogę sobie z tym poradzić w stylu pisania kaczego, jak wspominają inni. Skąd mam wiedzieć, że ciąg jest naprawdę ciągiem? Cóż, oczywiście poprzez konwersję na ciąg!
def myfunc(word):
word = unicode(word)
...
Jeśli argument jest już ciągiem lub typem Unicode, słowo real_word zachowa swoją wartość bez modyfikacji. Jeśli przekazany obiekt implementuje __unicode__
metodę, która jest używana do uzyskania jego reprezentacji Unicode. Jeśli przekazany obiekt nie może być użyty jako ciąg znaków, unicode
wbudowane polecenie generuje wyjątek.
isinstance(your_object, basestring)
będzie Prawda, jeśli Twój obiekt jest rzeczywiście ciągiem znaków. „str” to słowo zastrzeżone.
przepraszam, poprawną odpowiedzią jest użycie „łańcucha bazowego” zamiast „str”, aby zawierał także łańcuchy Unicode - jak zauważono powyżej przez jednego z pozostałych respondentów.
Tego wieczoru wpadłem na sytuację, w której myślałem, że będę musiał sprawdzić przedstr
typ, ale okazało się, że nie.
Moje podejście do rozwiązania problemu będzie prawdopodobnie działało w wielu sytuacjach, dlatego oferuję je poniżej, na wypadek, gdyby inni czytający to pytanie byli zainteresowani (tylko Python 3).
# NOTE: fields is an object that COULD be any number of things, including:
# - a single string-like object
# - a string-like object that needs to be converted to a sequence of
# string-like objects at some separator, sep
# - a sequence of string-like objects
def getfields(*fields, sep=' ', validator=lambda f: True):
'''Take a field sequence definition and yield from a validated
field sequence. Accepts a string, a string with separators,
or a sequence of strings'''
if fields:
try:
# single unpack in the case of a single argument
fieldseq, = fields
try:
# convert to string sequence if string
fieldseq = fieldseq.split(sep)
except AttributeError:
# not a string; assume other iterable
pass
except ValueError:
# not a single argument and not a string
fieldseq = fields
invalid_fields = [field for field in fieldseq if not validator(field)]
if invalid_fields:
raise ValueError('One or more field names is invalid:\n'
'{!r}'.format(invalid_fields))
else:
raise ValueError('No fields were provided')
try:
yield from fieldseq
except TypeError as e:
raise ValueError('Single field argument must be a string'
'or an interable') from e
Niektóre testy:
from . import getfields
def test_getfields_novalidation():
result = ['a', 'b']
assert list(getfields('a b')) == result
assert list(getfields('a,b', sep=',')) == result
assert list(getfields('a', 'b')) == result
assert list(getfields(['a', 'b'])) == result
To proste, użyj następującego kodu (zakładamy, że wspomniany obiekt to obj) -
if type(obj) == str:
print('It is a string')
else:
print('It is not a string.')
Możesz to przetestować, łącząc pusty ciąg:
def is_string(s):
try:
s += ''
except:
return False
return True
Edytuj :
Poprawiam moją odpowiedź po komentarzach wskazujących, że nie udaje się to z listami
def is_string(s):
return isinstance(s, basestring)
Aby uzyskać dobre podejście do pisania w stylu „kaczych znaków”, które ma tę zaletę, że współpracuje zarówno z Pythonem 2.x, jak i 3.x:
def is_string(obj):
try:
obj + ''
return True
except TypeError:
return False
mądry był blisko pisania kaczką, zanim przeszedł na isinstance
podejście, z wyjątkiem tego, że +=
ma inne znaczenie dla list niż +
ma.
isalpha
, ale kto wie, jakich metod można by bezpiecznie szukać?
__str__
metoda oraz równość może faktycznie być jeden idiotoodporny. Ale nawet to nie jest bez zastrzeżeń.
try
może być szybszy. Jeśli oczekujesz, że 99% czasu, może nie. Różnica w wydajności jest minimalna, lepiej być idiomatycznym, chyba że profilujesz swój kod i nie identyfikujesz go jako wolnego.
if type(varA) == str or type(varB) == str:
print 'string involved'
z EDX - kurs online MITx: 6.00.1x Wprowadzenie do informatyki i programowania za pomocą Pythona
str
!