Bagaimana cara mengetahui apakah objek Python adalah string?

402

Bagaimana saya bisa memeriksa apakah objek Python adalah string (baik reguler atau Unicode)?

Matt S.
sumber
18
Apa yang dimaksud Jason adalah mengetik bebek (jika dukun seperti bebek mungkin adalah bebek). Dalam Python Anda sering "membiarkan kode Anda bekerja" pada objek string-seperti apa pun tanpa menguji apakah itu string atau subkelas string. Untuk info lebih lanjut, lihat: docs.python.org/glossary.html#term-duck-typing
Ben Hoyt
4
Itulah yang saya sukai dari SO. Saya biasanya mengajukan pertanyaan, itu tidak dijawab, orang mengatakan kepada saya bahwa saya seharusnya tidak melakukan itu dan mengapa, dan saya tumbuh sebagai seorang programmer. =)
physicsmichael
24
+1: Hanya karena jawaban jarang diperlukan, bukan berarti pertanyaannya tidak valid. Meskipun, saya pikir itu baik untuk berhati-hati di sini, saya pikir itu tidak layak menurunkan pertanyaan.
Trevor
17
Ini mungkin penggunaan yang paling sah dari pemeriksaan tipe dengan Python. String dapat diubah, jadi membedakannya dari daftar dengan cara lain adalah ide yang buruk.
ojrac
3
Pasti ada kasus di mana perlu untuk membedakan string dari iterables lainnya. Sebagai contoh, lihat kode sumber untuk PrettyPrinter di modul pprint.
saxman01

Jawaban:

302

Python 2

Gunakan isinstance(obj, basestring)untuk objek-untuk-tes obj.

Documents .

John Fouhy
sumber
178

Python 2

Untuk memeriksa apakah suatu objek oadalah tipe string dari subkelas dari tipe string:

isinstance(o, basestring)

karena keduanya strdan unicodemerupakan subclass dari basestring.

Untuk memeriksa apakah jenisnya otepat str:

type(o) is str

Untuk memeriksa apakah oturunan dari stratau subkelas dari str:

isinstance(o, str)

Di atas juga berfungsi untuk string Unicode jika Anda mengganti strdengan unicode.

Namun, Anda mungkin tidak perlu melakukan pengecekan tipe eksplisit sama sekali. "Mengetik bebek" mungkin sesuai dengan kebutuhan Anda. Lihat http://docs.python.org/glossary.html#term-duck-typing .

Lihat juga Apa cara kanonik untuk memeriksa jenis python?

Matt S.
sumber
variabel lokal 'str' dirujuk sebelum penugasan
john ktejik
@johnktejik python3 vs python2. Anda perlu memeriksa basestringdi py2.
erikbwork
170

Python 3

Dalam Python 3.x basestringtidak tersedia lagi, seperti strjenis string tunggal (dengan semantik Python 2.x's unicode).

Jadi cek di Python 3.x hanya:

isinstance(obj_to_test, str)

Ini mengikuti perbaikan2to3 alat konversi resmi : konversi basestringke str.

sevenforce
sumber
94

Python 2 dan 3

(kompatibel lintas)

Jika Anda ingin memeriksa tanpa memperhatikan versi Python (2.x vs 3.x), gunakan six( PyPI ) dan string_typesatributnya:

import six

if isinstance(obj, six.string_types):
    print('obj is a string!')

Dalam six(modul file tunggal yang sangat ringan), cukup lakukan ini :

import sys
PY3 = sys.version_info[0] == 3

if PY3:
    string_types = str
else:
    string_types = basestring
Nick T
sumber
Atau, Anda dapat menggunakan future( PyPI ) bahkan untuk menjaga nama:from past.builtins import basestring
David Nemeskey
1
BTW the Cheat Sheet adalah sumber yang bagus untuk kompatibilitas versi Python.
David Nemeskey
1
Bagaimana dengan tidak menggunakan impor? Pertama coba basestringdan kemudian jatuh kembali ke str. Misalnyadef is_string(obj): try: return isinstance(obj, basestring) # python 2 except NameError: return isinstance(obj, str) # python 3
isaacbernat
19

Saya menemukan ini lagi pythonic:

if type(aObject) is str:
    #do your stuff here
    pass

karena jenis benda yang tunggal, yang dapat digunakan untuk melakukan membandingkan objek dengan jenis str

Zhou Jingyuan
sumber
4
Ini bukan cara yang disarankan umum untuk pengujian jenis, karena warisan: isinstance(obj_to_test, str)jelas dimaksudkan untuk menguji jenis, dan memiliki keuntungan menggunakan prosedur yang sama seperti untuk kasus-kasus non-str lainnya.
Eric O Lebigot
14

Jika seseorang ingin tinggal jauh dari eksplisit jenis-memeriksa (dan ada yang alasan yang baik untuk tinggal jauh dari itu), mungkin bagian paling aman dari protokol string untuk cek adalah:

str(maybe_string) == maybe_string

Itu tidak akan beralih melalui iterable atau iterator, itu tidak akan memanggil daftar string sebuah string dan itu benar mendeteksi stringlike sebagai string.

Tentu saja ada kekurangannya. Misalnya, str(maybe_string)mungkin perhitungan yang berat. Seperti yang sering terjadi, jawabannya tergantung .

EDIT: Seperti @Tcll tunjukkan dalam komentar, pertanyaan sebenarnya meminta cara untuk mendeteksi string unicode dan bytestrings. Pada Python 2 jawaban ini akan gagal dengan pengecualian untuk string unicode yang berisi karakter non-ASCII, dan pada Python 3 itu akan kembali Falseuntuk semua bytestrings.

klak
sumber
Dalam kasus objek yang diinisialisasi dengan data representasi, ini mungkin tidak berfungsi seperti yang diharapkan ... di b = b'test'; r = str(b) == bmana bmenyimpan data yang sama seperti str(b)tetapi (menjadi objek byte) tidak memvalidasi sebagai string.
Tcll
@Tcll Benar, pertanyaannya sebenarnya mengatakan "reguler atau Unicode". Saya kira saya tidak membacanya dengan benar.
clacke
11

Untuk memeriksa apakah variabel Anda adalah sesuatu, Anda dapat melakukan seperti:

s='Hello World'
if isinstance(s,str):
#do something here,

Output isistance akan memberi Anda nilai Boolean True atau False sehingga Anda dapat menyesuaikannya. Anda dapat memeriksa akronim yang diharapkan dari nilai Anda dengan awalnya menggunakan: type (s) Ini akan mengembalikan Anda mengetik 'str' sehingga Anda dapat menggunakannya dalam fungsi isistance.

Abraam Georgiadis
sumber
5

Saya mungkin berurusan dengan ini dalam gaya mengetik bebek, seperti yang disebutkan orang lain. Bagaimana saya tahu string benar-benar sebuah string? baik, jelas dengan mengubahnya menjadi string!

def myfunc(word):
    word = unicode(word)
    ...

Jika arg sudah menjadi tipe string atau unicode, real_word akan mempertahankan nilainya tidak dimodifikasi. Jika objek yang lewat mengimplementasikan __unicode__metode, yang digunakan untuk mendapatkan representasi unicode-nya. Jika objek yang dilewati tidak dapat digunakan sebagai string, unicodebuiltin memunculkan eksepsi.

SingleNegationElimination
sumber
3
isinstance(your_object, basestring)

akan menjadi True jika objek Anda memang tipe string. 'str' adalah kata yang dilindungi undang-undang.

maaf, jawaban yang benar adalah menggunakan 'basestring' alih-alih 'str' untuk memasukkan string unicode juga - seperti yang disebutkan di atas oleh salah satu responden lainnya.

bip
sumber
Tidak berfungsi untuk objek unicode, yang diminta secara eksplisit dalam pertanyaan.
dbn
1

Malam ini saya mengalami situasi di mana saya pikir saya harus memeriksa strjenisnya, tetapi ternyata saya tidak melakukannya.

Pendekatan saya untuk memecahkan masalah mungkin akan berhasil dalam banyak situasi, jadi saya menawarkannya di bawah jika orang lain yang membaca pertanyaan ini tertarik (hanya 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

Beberapa tes:

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
Rick mendukung Monica
sumber
1

Sederhana, gunakan kode berikut (kami menganggap objek yang disebutkan sebagai objek) -

if type(obj) == str:
    print('It is a string')
else:
    print('It is not a string.')
Abhijeet.py
sumber
0

Anda dapat mengujinya dengan menggabungkan dengan string kosong:

def is_string(s):
  try:
    s += ''
  except:
    return False
  return True

Edit :

Mengoreksi jawaban saya setelah komentar menunjukkan bahwa ini gagal dengan daftar

def is_string(s):
  return isinstance(s, basestring)
georgepsarakis
sumber
Anda benar, terima kasih telah menunjukkan. Saya telah memberikan jawaban alternatif.
georgepsarakis
-3

Untuk pendekatan pengetikan bebek yang bagus untuk string-like yang memiliki bonus bekerja dengan kedua Python 2.x dan 3.x:

def is_string(obj):
    try:
        obj + ''
        return True
    except TypeError:
        return False

ikan bijak dekat dengan mengetik bebek sebelum ia beralih ke isinstancependekatan, kecuali yang +=memiliki arti yang berbeda untuk daftar daripada yang +dilakukannya.

Alphadelta14
sumber
2
Anda memiliki dua downvotes dan tidak ada yang memberikan komentar. Saya belum downvoted tapi saya tidak suka solusi Anda karena: * Terlalu bertele-tele. Anda tidak perlu mendefinisikan fungsi untuk melakukan ini. * Mahal. Menangkap pengecualian tidak baik untuk kinerja. * Rawan kesalahan. Objek lain mungkin menerapkan menambahkan , melihat string, dan meningkatkan jenis pengecualian lain, yang bukan TypeError.
santiagobasulto
Juga di sini Anda menggunakan pendekatan mengetik bebek, yang indah, tetapi berakhir dengan melempar dan menangkap pengecualian hanya untuk menemukan sesuatu, yang tidak indah.
Alexey Tigarev
Ini mungkin secara sah satu-satunya cara jitu untuk membedakan antara string-like dan beberapa iterable lainnya dari string. Orang bisa mencari atribut seperti isalpha, tetapi siapa yang tahu metode apa yang aman untuk dicari?
clacke
Saya menyadari bahwa __str__metode plus kesetaraan sebenarnya bisa menjadi metode yang bodoh. Tetapi bahkan itu bukan tanpa peringatan.
clacke
Pengecualian @santiagobasulto murah di Python. Jika Anda mengharapkan kesalahan 1% dari waktu, trybisa lebih cepat. Jika Anda mengharapkannya 99% dari waktu, mungkin tidak. Perbedaan kinerja yang minimal, lebih baik menjadi idiomatis kecuali jika Anda membuat kode profil dan mengidentifikasinya sebagai benar-benar lambat.
Nick T
-4
if type(varA) == str or type(varB) == str:
    print 'string involved'

dari EDX - kursus online MITx: 6.00.1x Pengantar Ilmu Komputer dan Pemrograman Menggunakan Python

William Clay
sumber
6
Ini mungkin cara terburuk untuk memeriksa. Tidak hanya mengecualikan objek unicode, bahkan mengecualikan subclass dari str!
augurar