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模塊的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拆分空字串或僅包含空格的字串將回傳 [],
>>> '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而獲得的字串, 如果樣式沒有找到,則不加改變地回傳string,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'static PyObject*\npy_\1(void)\n{',
... 'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'
snake執行邏輯
首先分析一下snake函式最里面的sub函式,先看下輸入引數,
string是s.replace('-', ' ')將待轉換的字串中的'-'使用' '替換,
pattern是'([A-Z]+)',其中(...)表示他是一個組合,匹配括號內的正則運算式,并在匹配完成之后,組合的內容可以被獲取,并可以在之后用\number轉義序列進行再次匹配或使用,例如上個例子中的\1,'([A-Z]+)'的組合表示要匹配一個或多個大寫字母,并盡可能匹配出最長的子字串,
repl是r' \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'
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/331964.html
標籤:Python
