Python代码阅读合集介绍:为什么不推荐Python初学者直接看项目源码本文阅读的代码将变量名转换为snake-style命名风格(蛇形)函数。本文阅读的代码片段来自30-seconds-of-python。snakefrom重新导入subdefsnake(s):返回“_”。join(sub('([A-Z][a-z]+)',r'\1',sub('([A-Z]+)',r'\1',s.replace('-',''))).split()).lower()#EXAMPLESsnake('camelCase')#'camel_case'snake('sometext')#'some_text'snake('some-mixed_stringWithspaces_underscores-and-hyphens')#'some_mixed_string_with_spaces_underscores_and_hyphens'snake('AllThe-smallThings')#"all_the_small_things"snake函数使用正则表达式将字符串扭曲和分解为单词,添加_作为分隔符组合。该函数主要使用了re模块的sub、str.replace、str.split、str.lower和str.join。在正式分析snake函数的逻辑之前,先介绍一下其中用到的其他函数的作用。str.replace(old,new[,count])返回字符串的副本,其中所有出现的子字符串old都将替换为new如果给出了可选参数count,则只会替换第一个出现的count次。str.split(sep=None,maxsplit=-1)返回字符串中单词的列表,使用sep作为分隔符。如果给出了maxsplit,则最多进行maxsplit拆分(因此,列表将最多有maxsplit+1个元素)。如果maxsplit未指定或为-1,则拆分次数不受限制(进行所有可能的拆分)。如果未指定sep或为None,则将应用另一种拆分算法:连续的空格将被视为单个分隔符,如果开头和结尾包含空格,则不会拆分空字符串。因此,使用None拆分空字符串或仅包含空格的字符串将返回[]。>>>'123'.split()['1','2','3']>>>'123'.split(maxsplit=1)['1','23']>>>'123'.split()['1','2','3']str.join(iterable)返回一个由iterable中的字符串拼接而成的字符串。str.lower()返回原始字符串的副本,其中所有区分大小写的字符都转换为小写。re.sub(pattern,repl,string,count=0,flags=0)返回通过用repl替换string中pattern的最左边非重叠出现而获得的字符串。如果未找到样式,则返回字符串不变。repl可以是字符串或函数。像\6这样的反向引用被替换为与模式的第6组匹配的子字符串。比如下面的例子,第一组匹配的是myfun,所以替换的时候,\1被myfun替换了,所以结果中\npy_后面跟着myfun。以'r'为前缀的字符串是原始字符串,反斜杠不必做任何特殊的事情。所以r"\n"表示包含'\'和'n'两个字符的字符串,而"\n"表示只包含一个换行符的字符串。>>>re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',...r'staticPyObject*\npy_\1(void)\n{',...'defmyfunc():')'staticPyObject*\npy_myfunc(void)\n{'snake执行逻辑先分析snake函数最里面的sub功能。先看输入参数。stringiss.replace('-','')将待转换字符串中的'-'替换为''。模式为'([A-Z]+)',其中(...)表示是一个组合,匹配括号中的正则表达式,匹配完成后,可以得到组合的内容,以及后面可以使用\number转义序列来匹配或者再次使用,比如前面例子中的\1。'([A-Z]+)'的组合表示匹配一个或多个大写字母,尽可能匹配最长的子串。repl为r'\1',表示在组合匹配的字符串前加一个空格,替换匹配的字符串。例如'abcDEF'匹配替换后会变成'abcDEF'。sub('([A-Z]+)',r'\1','abcDEF')#'abcDEF'所以snake函数最里面的sub函数的输出就是用原字符串中的'-'用''替换,然后匹配字符串中一个或多个连续的大写字母,前面加一个空格。例如,原始字符串是'abc-abcDEF-ABc',经过第一个子函数转换为'abcabcDEFABc'(注意'ABc'前面有两个空格)。接下来分析第二层的子功能。还是先看输入参数。string是前一个sub的输出,在前面的例子中,'abcabcDEFABc'(注意'ABc'之前的两个空格)。模式是“([A-Z][a-z]+)”。它也是一个组合,意思是匹配一个大写字母后跟一个或多个小写字母,并匹配可能的最长子串。repl仍然是r'\1',意思是在组合匹配的字符串前加一个空格,替换匹配的字符串。因此,第二级sub的输出只是匹配一个大写字母,后面跟着一个或多个小写字母,前面是一个空格。继续前面的例子,这一层的输入字符串是'abcabcDEFABc'(注意'ABc'之前的两个空格),输出是'abcabcDEFABc'(注意'A'之前的两个空格).然后snake函数将第二层sub输出的字符串使用str.split函数分割成一个字符串列表。然后使用“-”作为分隔符组合生成的字符串列表。最后使用str.lower将合并后的字符串转换为小写。继续上面的例子,最终输出的字符串是:'abc_abc_def_a_bc'
