有没有办法判断 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 中它们给出 str
和 unicode
。因此,也许您可以另辟蹊径,确保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'?的主要内容,如果未能解决你的问题,请参考以下文章