如何检查变量是否为具有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
Unicode文字的u“”语法在Python 3.3中重新引入
jfs 2012年

奇。我在Python 2.7.16上得到```>>> isinstance(u“ test”,basestring)
True```– Darakian

Answers:


209

如果要编写兼容2.x和3.x的代码,则可能要使用六个

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 2013年

1
@ Chandler.Huang这个问题是关于识别strunicode对Python 2中,或strPython的3.如果你不想unicode指望Python 2中,只需要使用str
ecatmur '16

@ecatmur哇,谢谢!删除了它,所以没有人感到困惑
runDOSrun '17

4
您也可以从future包装中使用它,而不是sixfrom future.utils import string_types
SuperGeo

113

我发现不依赖六个软件包的最简洁的方法是:

try:
  basestring
except NameError:
  basestring = str

然后,假设您以最通用的方式检查了Python 2中的字符串,

isinstance(s, basestring)

现在也将适用于Python 3+。


10
对于py3,basestring = (str, bytes)摘自requests/compat.py
Tanky Woo,

很好,但是为什么呢?如果Python3在这里向后兼容,那就太好了。以上解决方案有效。如果没有必要的话会更好。
guettli

2
为了满足这两个PY2和3支持和mypy,我结束了if not hasattr(__builtins__, "basestring"): basestring = (str, bytes)
戴夫·李

35

那在所有情况下都可行吗?

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

@holdenweb:否,是的,我认为是一个不错的“仅在需要时影响”的技巧。
Dilettant

1
我喜欢这个答案的原因是它很友好,可以从python2迁移到
3。– Tiagojdferreira

4
我还使用了该选项,将其包装在辅助函数中,因此它仅出现一次,并且在文档字符串中有一个位置可归功于Fil。
卡尔·史密斯

2
整洁,我自己使用它,直到意识到自己也很from __future__ import unicode_literals活跃。现在我要去:isinstance(val, (str, u"".__class__))
Graham Klyne '18

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)

抱歉给您带来bug,但是在Window 7下使用Python 3.2.3 isinstance(u'hello', basestr)可以SyntaxError: invalid syntax为我带来收益。它似乎并不像u-我得到这个错误与strbasestr
捷尔

1
@Levon没问题:)那是因为Python3没有该语法,因为strPython3根据定义是Unicode。因此,没有basestring类型,因此该类型NameError被我的代码段捕获。
Lev Levitsky

现在它确实具有该语法。在3.3中
Randall Hunt

2
我建议一次执行一次try/ except测试,并根据该次测试的结果isstr()正确定义。每次调用时都无需产生异常的开销isstr()
steveha

@Ranman对Python 3.3是正确的,这是PEP的链接。
Lev Levitsky

7

您可以通过调用来获取对象的类object.__class__,以便检查object是否为默认字符串类型:

    isinstance(object,"".__class__)

而且您可以将以下内容放在代码的顶部,以便用引号括起来的字符串在python 2中的unicode中:

    from __future__ import unicode_literals

我这个解决方案很多。我发现定义str =“” .__ class__很有用,现在可以正常编写isinstance(object,str),并确保str(object)在Python 2和Python 3中都返回一个unicode字符串。
2013年

解析XML时,此方法不起作用:some_element.text是'str',但与'unicode'的比较将失败
Vault

不适用于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,str并且bytes基本上是相同的。如果您试图区分两者,则可能会导致错误。

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

-4

类型(字符串)== str

如果它是一个字符串,则返回true;否则,则返回false


1
对于Python 2而言不是正确的,那里string是一个unicode字符串
lxop '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.