乐趣区

关于python:Python代码阅读第21篇将变量名称转换为蛇式命名风格

Python 代码浏览合集介绍:为什么不举荐 Python 初学者间接看我的项目源码

本篇浏览的代码实现将变量名称转换为蛇式命名格调(snake case)的性能。

本篇浏览的代码片段来自于 30-seconds-of-python。

snake

from re import sub

def snake(s):
  return '_'.join(sub('([A-Z][a-z]+)', r'\1',
    sub('([A-Z]+)', r'\1',
    s.replace('-', ' '))).split()).lower()

# EXAMPLES
snake('camelCase') # 'camel_case'
snake('some text') # 'some_text'
snake('some-mixed_string With spaces_underscores-and-hyphens') # 'some_mixed_string_with_spaces_underscores_and_hyphens'
snake('AllThe-small Things') # "all_the_small_things"

snake函数应用正则表达式将字符串变形、分解成单词,并加上 _ 作为分隔符组合起来。函数次要应用了 re 模块的 substr.replacestr.splitstr.lowerstr.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 拆分空字符串或仅蕴含空格的字符串将返回 []

>>> '1 2 3'.split()
['1', '2', '3']
>>> '1 2 3'.split(maxsplit=1)
['1', '2 3']
>>> '1   2   3'.split()
['1', '2', '3']

str.join(iterable)

返回一个由 iterable 中的字符串拼接而成的字符串。

str.lower()

返回原字符串的正本,其所有辨别大小写的字符均转换为小写。

re.sub(pattern, repl, string, count=0, flags=0)

返回通过应用 repl 替换在 string 最右边非重叠呈现的 pattern 而取得的字符串。如果款式没有找到,则不加扭转地返回 stringrepl 能够是字符串或函数。向后援用像是 \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'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'

snake执行逻辑

首先剖析一下 snake 函数最外面的 sub 函数。先看下输出参数。

strings.replace('-', '') 将待转换的字符串中的 '-' 应用 ' ' 替换。

pattern'([A-Z]+)',其中(...) 示意他是一个组合,匹配括号内的正则表达式,并在匹配实现之后,组合的内容能够被获取,并能够在之后用 \number 转义序列进行再次匹配或应用,例如上个例子中的 \1'([A-Z]+)' 的组合示意要匹配一个或多个大写字母,并尽可能匹配出最长的子字符串。

replr'\1',代表应用组合匹配进去的字符串前减少一个空格,替换匹配进去的字符串。例如'abcDEF' 通过匹配和替换将变成'abc DEF'sub('([A-Z]+)', r'\1', 'abcDEF') # 'abc DEF'

因而,snake函数最外面的 sub 函数的输入是将原始字符串中的 '-' 应用 '' 替换,再匹配字符串中的一个或多个间断的大些字母,在后面减少一个空格。例如原始字符串是 'abc-abcDEF-ABc' 通过第一个 sub 函数转换后变成 'abc abc DEF ABc'(留神'ABc' 后面有两个空格)。

接下来再剖析一下第二层的 sub 函数。还是先看一下输出参数。

string是上个 sub 的输入,在后面的例子中,是 'abc abc DEF ABc'(留神'ABc' 后面有两个空格)。

pattern'([A-Z][a-z]+)'。它也是一个组合,示意要匹配一个大写字母前面跟着一个或多个小写字母的模式,并尽可能匹配出最长的子字符串。

repl还是r'\1',代表应用组合匹配进去的字符串前减少一个空格,替换匹配进去的字符串。

因而,第二层 sub 的输入是简略的匹配一个大写字母前面跟着一个或多个小写字母的模式,在后面加一个空格。持续应用后面的例子,这层的输出字符串是 'abc abc DEF ABc'(留神'ABc' 后面有两个空格),输入是 'abc abc DEF A Bc'(留神'A' 后面有两个空格)。

而后 snake 函数将第二层 sub 输入的字符串应用 str.split 函数分成字符串列表。再将失去的字符串列表应用 '-' 作为分隔符组合起来。最初应用 str.lower 将组合后的字符串转换成小写。连续下面的例子,最终输入的字符串为:'abc_abc_def_a_bc'

退出移动版