Python 内置函数str.lower()是如何实现的?
我想知道str.lower()是如何在Python中实现的,所以我克隆了存储库并用grep进行了一些搜索。在Python 内置函数str.lower()是如何实现的?,python,Python,我想知道str.lower()是如何在Python中实现的,所以我克隆了存储库并用grep进行了一些搜索。在Objects/unicodeobject.c中从unicode\u lower开始几次跳转之后,我在Objects/unicodeotype.c中遇到了这个问题: int _PyUnicode_ToLowerFull(Py_UCS4 ch, Py_UCS4 *res) { const _PyUnicode_TypeRecord *ctype = gettyperecord(ch)
Objects/unicodeobject.c
中从unicode\u lower
开始几次跳转之后,我在Objects/unicodeotype.c
中遇到了这个问题:
int _PyUnicode_ToLowerFull(Py_UCS4 ch, Py_UCS4 *res)
{
const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
if (ctype->flags & EXTENDED_CASE_MASK) {
int index = ctype->lower & 0xFFFF;
int n = ctype->lower >> 24;
int i;
for (i = 0; i < n; i++)
res[i] = _PyUnicode_ExtendedCase[index + i];
return n;
}
res[0] = ch + ctype->lower;
return 1;
}
int-PyUnicode-ToLowerFull(Py-UCS4-ch,Py-UCS4*res)
{
const _PyUnicode_TypeRecord*ctype=gettyperecord(ch);
如果(ctype->标志和扩展大小写掩码){
int index=ctype->lower&0xFFFF;
int n=ctype->lower>>24;
int i;
对于(i=0;ilower;
返回1;
}
我熟悉C语言,但对python的实现方式并不熟悉(但我想改变这一点!)。我真的不明白到底发生了什么,所以在这里寻求帮助以获得一些明确的解释。在您显示的函数中有两个分支。运行哪个分支取决于所讨论字符的
\u PyUnicode\u TypeRecord
字段的标志
字段。如果它设置了EXTENDED\u CASE\u MASK
位,则会运行更复杂的代码位,否则会使用更简单的版本
让我们先看一下简单的部分:
res[0] = ch + ctype->lower;
return 1;
这只需将lower
字段的值作为偏移量添加到输入码点,将其分配到res
返回参数的第一位,并返回1
(因为它使用了一个字符)
现在来看更复杂的版本:
int index = ctype->lower & 0xFFFF;
int n = ctype->lower >> 24;
int i;
for (i = 0; i < n; i++)
res[i] = _PyUnicode_ExtendedCase[index + i];
return n;
int index=ctype->lower&0xFFFF;
int n=ctype->lower>>24;
int i;
对于(i=0;i
在此版本中,lower
字段被解释为两个不同的数字。最低的16位是索引
,而最高的位变成n
(要输出的字符数)。然后,代码在\u PyUnicode\u ExtendedCase
数组中的n
字符上循环,从索引开始,将它们复制到res
数组中。最后,它返回使用的字符数
需要更复杂的代码来处理表示两个字符连字的Unicode代码点的大小写更改(通常是出于模糊的历史原因,例如,在古代可移动式打印中,它们可能位于单个类型块上)。这些连字可能只存在于一种情况下,如果字符在其他情况下没有重叠那么多。例如,字符'fl'
是小写字符'f'
和'l'
的连字。不存在连字的大写版本,因此'FL'.upper()
需要返回两个字符的字符串('FL'
).@Blckknght感谢您将我带到现在:\u PyUnicode\u ExtendedCase
基本上充当从小写/大写到小写的映射吗?\u PyUnicode\u ExtendedCase
来自何处?它看起来如何?我还不清楚“简单的部分”。为什么只修改数组中的第一个元素?它只考虑大写单词吗?\u PyUnicode\u ExtendedCase
数组在各种大小写之间映射,但它仅用于一个大小写中的一个字符映射到另一个大小写中的多个字符的情况。一对一映射是在我称之为“简单情况”的情况下处理的,这就是为什么代码的这部分只分配给输出数组中的一个字符。数据(包括\u PyUnicode\u ExtendedCase
和一个大型\u PyUnicode\u TypeRecord
s表等)在中定义。