Pythonオブジェクトが文字列かどうかを調べる方法は?


402

Pythonオブジェクトが文字列(通常またはUnicode)かどうかを確認するにはどうすればよいですか?


18
ジェイソンが言及しているのは、アヒルのタイピングです(アヒルのように鳴く場合は、おそらくアヒルです)。Pythonでは、文字列のようなオブジェクトでも、それが文字列であるか文字列サブクラスであるかをテストせずに、「コードを機能させる」ことがよくあります。詳細については、docs.python.org
Ben Hoytを

4
それが私がSOで気に入っていることです。私はたいてい質問をしますが、答えはありません。とにかくそんなことをしてはいけない、と言われ、プログラマーとして成長します。=)
physicsmichael 2009

24
+1:回答がほとんど必要ないからといって、質問が無効であるという意味ではありません。ここで注意を払うのは素晴らしいことだと思いますが、質問を降格するメリットはないと思います。
Trevor

17
これはおそらくPythonでの型チェックの最も正当な使用法です。文字列は反復可能であるため、他の方法でリストから区別することは悪い考えです。
ojrac 2013年

3
文字列を他のイテラブルと区別する必要がある場合は間違いありません。たとえば、pprintモジュールのPrettyPrinterのソースコードを参照してください。
saxman01 2014年

回答:



178

Python 2

オブジェクトoが文字列型のサブクラスの文字列型かどうかを確認するには:

isinstance(o, basestring)

両方のためにstrunicodeのサブクラスですbasestring

のタイプoが正確かどうかを確認するにはstr

type(o) is str

oインスタンスstrまたはそのサブクラスであるかどうかを確認するにはstr

isinstance(o, str)

あなたが交換する場合は、Unicode文字列のためにも、上記の作業strunicode

ただし、明示的な型チェックをまったく行う必要がない場合もあります。「ダックタイピング」はあなたのニーズに合うかもしれません。http://docs.python.org/glossary.html#term-duck-typingを参照してください。

も参照してくださいPythonでタイプをチェックするための正規の方法は何ですか?


割り当て前に参照されるローカル変数「str」
john ktejik '30 / 10/30

@johnktejik python3対python2。basestringpy2で確認する必要があります。
erikbwork

170

Python 3

Python 3.xでは、唯一の文字列型(Python 2.xのセマンティクスを持つ)とbasestring同様strに、もう使用できませんunicode

したがって、Python 3.xでのチェックは次のとおりです。

isinstance(obj_to_test, str)

これは、以下の修正公式の2to3変換ツールを:変換basestringしますstr


94

Python 2および3

(相互互換)

Pythonバージョン(2.xと3.x)を考慮せずに確認する場合は、sixPyPI)とそのstring_types属性を使用します。

import six

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

six(非常に軽量の単一ファイルモジュール)、それは単にやっているこれを

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

if PY3:
    string_types = str
else:
    string_types = basestring

別の方法としては、使用することができますfutureは、PyPI:名前さえ維持するために)from past.builtins import basestring
デヴィッド・Nemeskey

1
ちなみに、チートシートは、Pythonバージョンの互換性に関する優れたリソースです。
David Nemeskey 2017

1
インポートを使用しないのはどうですか?最初に試しbasestring、次ににフォールバックしstrます。例def is_string(obj): try: return isinstance(obj, basestring) # python 2 except NameError: return isinstance(obj, str) # python 3
isaacbernat 2017

19

私はこれをもっと見つけましたpythonic

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

型オブジェクトはシングルトンであるため、 STR型と比較オブジェクトを実行するために使用することができます


4
継承のため、これは型のテストの一般的な推奨方法ではありません。isinstance(obj_to_test, str)明らかに型のテストを意図しており、str以外の場合と同じ手順を使用できるという利点があります。
Eric O Lebigot

14

明示的な型チェックを避けたい場合(そしてそれを避けた方よい理由がある場合)、チェックする文字列プロトコルの最も安全な部分は次のとおりです。

str(maybe_string) == maybe_string

iterableまたはiteratorを反復処理せず、string-of-stringsを文字列と呼ばず、stringlikeを文字列として正しく検出します。

もちろん欠点もあります。たとえばstr(maybe_string)、重い計算になる場合があります。よくあることですが、答えはそれによって異なります。

編集:@Tcll がコメントで指摘しているように、質問は実際にはUnicode文字列とバイト文字列の両方を検出する方法を求めています。Python 2ではこの回答は失敗しますが、ASCII以外の文字を含むUnicode文字列は例外で、Python 3ではFalseすべてのバイト文字列に対して返されます。


表現データを初期化するオブジェクトの場合、これは予想通りに動作しない場合があり... b = b'test'; r = str(b) == b場合bと同じデータを保持しているstr(b)が、(あるオブジェクトをバイト)の文字列として検証されません。
Tcll

@Tcllそうです、質問は実際には「通常またはUnicode」のどちらかです。きちんと読まなかったと思います。
1

11

変数が次のようなものかどうかを確認するには:

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

isistanceの出力はブール値のTrueまたはFalse値を提供するので、それに応じて調整できます。最初に次を使用して、値の予想される頭字語を確認できます。type(s)これにより、「str」が返されるので、isistance関数で使用できます。


5

他の人が言うように、私はこれをダックタイピングのスタイルで扱うかもしれません。文字列が本当に文字列であるとどうやって知るのですか?まあ、明らかそれを文字列に変換することによって!

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

argがすでに文字列またはUnicode型である場合、real_wordはその値を変更せずに保持します。渡されたオブジェクトが__unicode__メソッドを実装している場合、それはそのユニコード表現を取得するために使用されます。渡されたオブジェクトを文字列として使用できない場合、unicode組み込み関数は例外を発生させます。


3
isinstance(your_object, basestring)

オブジェクトが実際に文字列型の場合、Trueになります。「str」は予約語です。

申し訳ありませんが、正しい答えは、「str」ではなく「basestring」を使用して、Unicode文字列も含めることです。これは、他のレスポンダのいずれかによって前述されています。


質問で明示的に要求されたUnicodeオブジェクトには機能しません。
dbn 2014年

1

今晩、私はタイプをチェックする必要があると思った状況に出くわしましたstrが、実際にはそうではないことがわかりました。

問題を解決するための私のアプローチはおそらく多くの状況で機能するので、この質問を読んでいる他の人が興味を持っている場合に備えて、以下に提供します(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

いくつかのテスト:

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

1

その単純な方法は、次のコードを使用します(ここでは、オブジェクトがobjであると想定しています)

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

0

空の文字列と連結してテストできます。

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

編集

これはリストで失敗することを指摘しているコメントの後に私の答えを修正する

def is_string(s):
  return isinstance(s, basestring)

あなたは正しい、指摘してくれてありがとう。私は別の答えを出しました。
georgepsarakis 2013年

-3

Python 2.xと3.xの両方で作業できるというボーナスがある、文字列のようなダックタイピングアプローチの場合:

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

wisefishは、isinstanceアプローチに切り替える前にアヒルのタイピングに近かったが、+=リストに対して意味が異なる+


2
さて、あなたは2つの反対票を持っており、誰もコメントを提供していません。私は反対票を投じていませんが、次の理由であなたの解決策は好きではありません。*冗長すぎる。これを行うために関数を定義する必要はありません。* 高価な。例外をキャッチしてもパフォーマンスは良くありません。* エラーを起こしやすい。他のオブジェクトは、addを実装し、文字列を参照し、TypeErrorではない別のタイプの例外を発生させる場合があります。
santiagobasulto

また、ここでは、アヒルをタイピングするアプローチを採用しています。
Alexey Tigarev 2016年

これは、文字列のような文字列とその他の反復可能な文字列を区別するための唯一の確実な方法です。のような属性を探すこともできますが、探すのにisalpha安全なメソッドを知っているのは誰ですか?
2016

私はメソッドと等式が実際にばかげたことのないものであるかもしれないことに気づきまし__str__。しかし、それでも警告がないわけではありません。
2016

@santiagobasulto例外はPythonでは安価です。時間の1%のエラーが予想される場合は、tryより速くすることができます。99%の確率で期待できる場合は、そうではないかもしれません。パフォーマンスの違いは最小限であり、コードをプロファイリングして実際に低速であると識別しない限り、慣用的である方が良いです。
Nick T

-4
if type(varA) == str or type(varB) == str:
    print 'string involved'

EDXから-オンラインコースMITx:6.00.1x Pythonを使用したコンピュータサイエンスとプログラミング入門


6
これはおそらくチェックする最悪の方法です。Unicodeオブジェクトを除外するだけでなく、str!のサブクラスも除外します。
オーギュラー2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.