【发布时间】:2019-11-07 15:14:08
【问题描述】:
版本是 Python 3.7。我刚刚发现 python 有时会将字符 ñ 存储在具有多种表示形式的字符串中,我完全不知道为什么或如何处理它。
我不确定展示这个问题的最佳方式,所以我只展示一些代码输出。
我有两个字符串,s1 和 s2 都设置为等于 'Dan Peña'
它们都是字符串类型。
我可以运行代码:
print(s1 == s2) # prints false
print(len(s1)) # prints 8
print(len(s2)) # prints 9
print(type(s1)) # print 'str'
print(type(s2)) # print 'str'
for i in range(len(s1)):
print(s1[i] + ", " + s2[i])
循环的输出是:
D, D
a, a
n, n
,
P, P
e, e
ñ, n
a, ~
那么,是否有任何 python 方法来处理这些不一致,或者至少有一些关于 python 何时使用哪种表示的规范?
如果知道 Python 为何会选择以这种方式实现也很高兴。
编辑:
一个字符串是从 django 数据库中检索的,另一个字符串是从从列表目录调用解析文件名获得的字符串。
from app.models import Model
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **kwargs):
load_dir = "load_dir_name"
save_dir = "save_dir"
files = listdir(load_dir)
save_file_map = {file[:file.index("_thumbnail.jpg")]: f"{save_dir}/{file}" for file in files}
for obj in Model.objects.all():
s1 = obj.title
save_file_path = save_file_map[s1] # Key error when encountering ñ.
但是,当我搜索 save_file_map 字典时,我发现一个与 s1 完全相同的键,除了 ñ 被编码为字符 n~ 而不是字符 ñ。
请注意,我在上面的代码中使用 list dir 加载的文件首先基于 obj.title 字段命名,因此应保证具有该名称的文件位于 load_dir 目录中。
【问题讨论】:
-
字符的二进制编码有很多种。看起来您正在比较二进制编码,而不是将它们转换为字符串。
-
显示您如何设置
s1和s2。 -
对我来说,s='Dan Peña' 只显示 len(s) = 9。
-
@Barmar 它们都是我检查过的字符串类型。其中一个字符串是从 listdir 读取并从文件名中解析出来的,而其中一个字符串是从 Django 数据库 char 字段中读取的。
-
问题可能与字符串在数据库中的编码方式有关,您在获取它时没有正确转换它。
标签: python python-3.x string python-3.7 unicode-normalization