変数がPython 2および3互換の文字列かどうかを確認する方法


171

私が使用できることは承知しています:isinstance(x, str)python-3.xでもpython-2.xでも何かが文字列かどうかを確認する必要があります。ウィルisinstance(x, str)のpython-2.xので期待どおりに動作しますか?または、バージョンを確認して使用する必要がありますisinstance(x, basestr)か?

具体的には、python-2.x:

>>>isinstance(u"test", str)
False

とpython-3.xにはありません u"foo"


2
u「は」ユニコードリテラルの構文は、Python 3.3に再導入される
JFS

奇数。私は `` `>>> isinstance(u" test "、basestring)True` ``をPython 2.7.16で取得します
Darakian

回答:


209

2.xおよび-3.x互換のコードを記述している場合は、おそらく6つ使用する必要があります。

from six import string_types
isinstance(s, string_types)

申し訳ありませんが、次の結果について少し混乱しています。 >>> isinstance(u"foo", string_types) True >>> isinstance(u"foo".encode("utf-8"), string_types) True isinstance(u "foo"、string_types)がfalseを返すことを期待していました。
Chandler.Huang

1
@ Chandler.Huangこの質問は、Python 2またはPython 3の特定strとその問題に関するものです。Python2 を数えたくない場合は、を使用してください。unicodestrunicodestr
ecatmur 2016年

@ecatmurおっと、ありがとう!それを削除したので、
誰も

4
あなたもからそれを使用することができfuture代わりのパッケージsixfrom future.utils import string_types
SuperGeo

113

6のようなパッケージに依存せずに私が見つけた最も簡潔なアプローチは、次のとおりです。

try:
  basestring
except NameError:
  basestring = str

次に、Python 2で最も一般的な方法で文字列をチェックしていると仮定すると、

isinstance(s, basestring)

Python 3以降でも動作するようになりました。


10
py3の場合、basestring = (str, bytes)fromrequests/compat.py
Woo

いいけど、なぜ?ここでPython3に下位互換性があると便利です。上記のソリューションは機能します。必要がなければもっと良いでしょう。
guettli

2
py2&3のサポートとmypyの両方を満たすために、私は次のようになりましたif not hasattr(__builtins__, "basestring"): basestring = (str, bytes)
Dave Lee

35

これはどうですか、すべてのケースで機能しますか?

isinstance(x, ("".__class__, u"".__class__))

@holdenweb:いいえ、はい-気の利いた「必要な場所にのみ影響を与える」ハックだと思います。
Dilettant 2017年

1
私はこの答えを好きな理由は、それがpython2から3への移行との友好的であるということです
Tiagojdferreira

4
私もこのオプションを使用して、ヘルパー関数でラップしたので、一度しか表示されず、docstringにFilをクレジットする場所があります。
カールスミス

2
きちんとしているし、自分もfrom __future__ import unicode_literalsアクティブに使用していることに気づくまで、自分で使用していました。今私は一緒に行きます:isinstance(val, (str, u"".__class__))
グラハム・クライン

18

これは@Lev Levitskyの回答で、少し書き直されました。

try:
    isinstance("", basestring)
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

try/exceptテストが一度に行われ、その後、常に動作し、できるだけ高速で機能が定義されています。

編集:実際には、呼び出す必要さえありませんisinstance()。評価basestringして、次の結果が得られるかどうかを確認するだけですNameError

try:
    basestring  # attempt to evaluate basestring
    def isstr(s):
        return isinstance(s, basestring)
except NameError:
    def isstr(s):
        return isinstance(s, str)

isinstance()ただし、への呼び出しをフォローする方が簡単だと思います。


isinstance("", basestring)私が「呼び出す」とはどういう意味ですか。とにかく、+ 1。
Lev Levitsky

1
Pythonは非常に動的な言語であり、そのようなテストを行うことは決して悪くないと思います。これは、一度何かを理解し、それに基づいて常に正しい関数を設定するのに役立つテクニックです。+1をありがとう。
steveha

5
:として私はそれを書くだろうtry: string_types = basestring except NameError: string_types = str
JFS

12

futureライブラリは、(Pythonの2に)追加互換性のある名前のことができますので、Pythonの3書き込みを続けます。以下を簡単に実行できます。

from builtins import str
isinstance(x, str) 

それをインストールするには、単に実行しますpip install futureます。

注意点、それだけでサポートされpython>=2.6>=3.3が、それはより多くの近代的であるsixだけされて、使用している場合、推奨しますpython 2.5


8

多分次のような回避策を使用する

def isstr(s):
    try:
        return isinstance(s, basestring)
    except NameError:
        return isinstance(s, str)

申し訳ありませんがバグのために、あなたが、isinstance(u'hello', basestr)利回りSyntaxError: invalid syntax窓7の下でのPython 3.2.3を持つ私にとっては...任意のアイデアは、なぜこれがでしょうか?それは次のようには思えないu私はこのエラーを取得する- strbasestr
リヴォン

1
@Levon問題ありません:)これは、Python3の定義がUnicode であるため、Python3にはその構文がないためですstr。したがって、basestringタイプはないため、NameErrorそれは私のスニペットでキャッチされます。
Lev Levitsky

現在、その構文は何も実行していません。3.3
Randall Hunt

2
try/ exceptテストを1回行うことをお勧めしますisstr()。その1回のテストの結果に基づいて、正しく定義します。を呼び出すたびに例外のオーバーヘッドを負う必要はありませんisstr()
steveha

@RanmanはPython 3.3にぴったりです。ここにPEPリンクがあります。
Lev

7

を呼び出すことobject.__class__でオブジェクトのクラスを取得できるため、オブジェクトがデフォルトの文字列型かどうかを確認するには、次のようにします。

    isinstance(object,"".__class__)

そして、引用符で囲まれた文字列がpython 2でユニコードになるように、コードの先頭に次のように配置できます。

    from __future__ import unicode_literals

私はこのソリューションをかなり使用しています。str = "" .__ class__を定義すると便利です。これにより、isinstance(object、str)を正常に書き込むことができるようになり、str(object)がPython 2とPython 3の両方でUnicode文字列を確実に返すようになります。
amicitas 2013

これsome_element.textは、XMLの解析時には機能しません:は「str」ですが、「unicode」との比較は失敗します
ボールト

Python 2のUnicode文字列では機能しません:isinstance(u'XXX '、' '.__ class__)== False
Fil

0

コードの最初でこれを試すことができます:

from __future__ import print_function
import sys
if sys.version[0] == "2":
    py3 = False
else:
    py3 = True
if py3: 
    basstring = str
else:
    basstring = basestring

そして後でコード:

anystring = "test"
# anystring = 1
if isinstance(anystring, basstring):
    print("This is a string")
else:
    print("No string")

0

注意してください!Python 2ではstrbytes基本的に同じです。この2つを区別しようとすると、バグが発生する可能性があります。

>>> size = 5    
>>> byte_arr = bytes(size)
>>> isinstance(byte_arr, bytes)
True
>>> isinstance(byte_arr, str)
True

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.