有没有办法判断 python 3 中的字符串前面是不是有明确的 'u'?

Posted

技术标签:

【中文标题】有没有办法判断 python 3 中的字符串前面是不是有明确的 \'u\'?【英文标题】:Is there a way to tell if a string in python 3 has an explicit 'u' in front of it?有没有办法判断 python 3 中的字符串前面是否有明确的 'u'? 【发布时间】:2022-01-21 16:05:37 【问题描述】:

我正在研究 python 2-3 的兼容性。使用 str 和 byte 类型时,我遇到了一个问题。这是一个例子

# python 2
x = b"%r" % u'hello' # this returns "u'hello'"

# python 3
x = b"%r" % u'hello' # this returns b"'hello'"

注意额外的 unicode u 如何出现在 python 2 中 x 的最终表示中?我需要让我的代码在 python3 和 python2 中返回相同的值。我的代码可以采用 str、bytes 或 unicode 值。

我可以通过这样做将 python 3 值强制转换为 python 2 值

# note: six.text_type comes from the six compatibility library. Basically checks to see if something is unicode in py2 and py3. 
new_data = b"%r" % original_input
if isinstance(original_input, six.text_type) and not new_data.startswith(b"u'"):
    new_data = b"u%s"

这使得u'hello' 案例工作正常,但搞砸了'hello' 案例。 这就是发生的事情:

# python 2
x = b"%r" % 'hello' # this returns "'hello'"

# python 3
x = b"%r" % 'hello' # this returns b"'hello'"

问题是在 python 3 中 u'hello''hello' 相同,所以如果我在上面包含我的代码,u'hello'hello' 的结果最终返回与 u'hello 相同的结果在python 3中。

所以我需要某种方法来判断 python 3 输入字符串是否在字符串前面明确指定了u,并且只有在满足这种情况时才执行我上面的代码。

【问题讨论】:

我认为在 Python 3 中所有字符串都是 Unicode,这就是它不再使用 u 前缀的原因。 是的,我认为 Barmar 是对的,如果你在 Python3 中使用 type("")type(u""),两者都给出 str,但在 Python2 中它们给出 strunicode。因此,也许您可​​以另辟蹊径,确保u 不会出现在 Python2 中,如果这符合您的要求的话。 这就像试图让你的代码用f(1+1)f(2) 做不同的事情。你为什么要这样做?您可能需要改变实现基本目标的方式。 @fooiey:但是您没有拥有 3 种类型的数据。您有 3 种方法可以写入 2 种类型的数据。您需要弄清楚 'asdf' 需要在哪里是字节,哪里需要是 Unicode 并适当地处理每种情况,而不是试图发明第三种数据类型 - 当我说你需要弄清楚这一点时,我的意思是实际人类在代码迁移过程中思考的事情,而不是某种会自动处理它的功能逻辑。 简短的回答是,你无法分辨,无论如何,不​​在 Python 代码中。 Python 3 中的 u 字符串前缀是无操作的,纯粹是为了简化 Python 2 代码的迁移。为了说明这一点,请在 Python 3 提示符下键入 u"hello" is "hello"。你会得到True。要做你想做的事,你必须自己解析源代码。尽管这足以表明您的方法需要工作。 【参考方案1】:

知道您当前正在执行的 python 版本并查看输入的类型是一件简单的事情。当然,这只是获取您拥有的数据并产生一致的输出。它不会从“原始源代码”中恢复语法糖,因为这不是您必须使用的数据。我只是想要一个一致的输出,就像你说的那样,“我需要让我的代码在 python3 和 python2 中返回相同的值。”

在 python2 中,您可能会处理 str 和 unicode。 在 python3 中你可能会处理字节和字符串。

先看python版本,因为如果你比较一个在那个版本中不存在的数据类型,它会在试图做检查时引发异常。

import six

if six.PY2:
    samples = ['hello', u'hello']
elif six.PY3:
    samples = ['hello', bytes('hello', 'utf-8')]
else:
    raise ValueError('python version unknown')

def normalize(message):
    if six.PY2:
        if type(message)==unicode:
            return str(message)
        elif type(message)==str:
            return message
        else:
            raise ValueError('expected string type, got ' + message.__class__.__name__)
    elif six.PY3:
        if type(message)==bytes:
            return message.decode('utf-8')
        elif type(message)==str:
            return message
        else:
            raise ValueError('expected string type, got ' + message.__class__.__name__)
    else:
        raise ValueError('python version unknown')

for message in samples:
    print(normalize(message))

这是在 2.7.5 和 3.9.2 上测试的 如果你在python2中有字节,它只是str的别名(https://***.com/a/5901825/1766544)

【讨论】:

这与问题所要求的完全不同。 我正在尝试使用 OP 的声明,即“我需要让我的代码在 python3 和 python2 中返回相同的值。”

以上是关于有没有办法判断 python 3 中的字符串前面是不是有明确的 'u'?的主要内容,如果未能解决你的问题,请参考以下文章

第一篇:python中的判断语句和循环

有没有办法匹配 Python ≥ 3.10 中的不等式?

Python基础11_Python中的字符串

Python Pandas:有没有办法根据列表中的字符串获取子集数据帧

在python列表中的每个项目的字符串前面添加一个字符串

python中有没有办法将存储在列表中的正则表达式模式列表应用于单个字符串?