【问题标题】:How to check if variable is string with python 2 and 3 compatibility如何检查变量是否为具有 python 2 和 3 兼容性的字符串
【发布时间】:2012-07-03 07:23:32
【问题描述】:

我知道我可以在 python-3.x 中使用:isinstance(x, str),但我还需要检查某些内容是否是 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"

【问题讨论】:

  • u"" Unicode 文字的语法在 Python 3.3 中重新引入
  • 奇数。我在 Python 2.7.16 上得到 ``` >>> isinstance(u"test", basestring) True ```

标签: python string python-3.x python-2.x


【解决方案1】:

如果您正在编写与 2.x 和 3.x 兼容的代码,您可能希望使用 six

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 这个问题是关于在 Python 2 上识别 strunicode,或者在 Python 3 上识别 str。如果你不希望 unicode 依赖 Python 2 ,只需使用str
  • @ecatmur 哎呀,谢谢!删除它,所以没有人会感到困惑
  • 你也可以从future包中使用它而不是six:from future.utils import string_types
【解决方案2】:

我发现的最简洁的方法是:

try:
  basestring
except NameError:
  basestring = str

那么,假设您一直在以最通用的方式在 Python 2 中检查字符串,

isinstance(s, basestring)

现在也适用于 Python 3+。

【讨论】:

  • 对于 py3,basestring = (str, bytes) 来自 requests/compat.py
  • 很好,但为什么呢?如果 Python3 在这里向后兼容就好了。以上解决方案有效。如果不需要它会更好。
  • 为了同时满足 py2 &3 的支持和 mypy,我最终得到了if not hasattr(__builtins__, "basestring"): basestring = (str, bytes)
【解决方案3】:

这个怎么样,在所有情况下都有效?

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

【讨论】:

  • @holdenweb:不,是的——我认为这是一个漂亮的“只在需要的地方影响”黑客攻击。
  • 我喜欢这个答案的原因是它对从python2迁移到3很友好。
  • 我也选择了这个选项,将它包装在一个辅助函数中,所以它只出现一次,并且在文档字符串中有一个位置可以归功于 Fil。
  • 整洁,我自己也在使用它,直到我意识到我也有from __future__ import unicode_literals 处于活动状态。现在我要去:isinstance(val, (str, u"".__class__))
【解决方案4】:

这是@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。
  • Python 是一种非常动态的语言,我认为进行这样的测试一点也不差。这是一种有用的技术,可以一次性解决问题,并在此基础上设置一个始终正确的函数。感谢您的 +1。
  • 我会写成:try: string_types = basestring except NameError: string_types = str
【解决方案5】:

future library 添加(到 Python 2)兼容名称,因此您可以继续编写 Python 3。您可以简单地执行以下操作:

from builtins import str
isinstance(x, str) 

要安装它,只需执行pip install future

作为一个警告,它只支持python>=2.6,>=3.3,但它比six更现代,只有recommended if using python 2.5

【讨论】:

  • from builtins import str; isinstance('foo', str) 在 python 2.7 中返回 False
  • 这不适用于 Python 2 字符串文字。
【解决方案6】:

也许使用类似的解决方法

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

【讨论】:

  • 很抱歉打扰您,但 isinstance(u'hello', basestr) 在 Window 7 下使用 Python 3.2.3 为我生成 SyntaxError: invalid syntax .. 知道为什么会这样吗?它似乎不喜欢u - 我收到strbasestr 的这个错误
  • @Levon 没问题 :) 那是因为Python3 doesn't have that syntax,正如 Python3 中的 str 定义为 Unicode。因此,没有 basestring 类型,因此我的 sn-p 中捕获了 NameError
  • 它现在确实具有该语法作为 noop。在 3.3 中
  • 我建议做一次try/except 测试,并根据那次测试的结果,正确定义isstr()。无需为每次调用 isstr() 产生异常开销。
  • @Ranman 对 Python 3.3 的看法是正确的,这里有一个指向 the PEP 的链接。
【解决方案7】:

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

    isinstance(object,"".__class__)

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

    from __future__ import unicode_literals

【讨论】:

  • 我这个解决方案相当多。我发现定义 str = "".__class__ 很有用,它现在允许 isinstance(object, str) 正常编写,并确保 str(object) 在 Python 2 和 Python 3 中都返回一个 unicode 字符串。
  • 这在解析 XML 时不起作用:some_element.text 是 'str' 但与 'unicode' 的比较会失败
  • 不适用于 python 2 上的 unicode 字符串:isinstance(u'XXX', ''.__class__) == False
【解决方案8】:

你可以在代码的开头试试这个:

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")

【讨论】:

    【解决方案9】:

    小心!在 python 2 中,strbytes 本质上是相同的。如果您试图区分两者,这可能会导致错误。

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

    【讨论】:

      【解决方案10】:

      类型(字符串)== str

      如果是字符串则返回true,否则返回false

      【讨论】:

      • 不适用于 Python 2,其中 string 是一个 unicode 字符串
      猜你喜欢
      • 1970-01-01
      • 2020-05-28
      • 2012-04-13
      • 2012-12-08
      • 2013-08-21
      • 2015-05-10
      • 1970-01-01
      • 2019-01-25
      • 2013-12-15
      相关资源
      最近更新 更多