Python 面試時(shí)千萬別這樣命名函數(shù),因?yàn)檫@個(gè)被淘汰可太不值了
在《11款常用的Python虛擬環(huán)境管理器》這篇文章中,我介紹了 Python 的虛擬環(huán)境,不知道大家有沒有自己動(dòng)手嘗試一下。
如果還沒有,建議大家親自安裝試一試,找到最適合自己的 Python 虛擬環(huán)境管理器。
本篇文章我想給大家講講 Python 標(biāo)識(shí)符命名的規(guī)范。
為什么要講標(biāo)識(shí)符命名呢?我講一個(gè)朋友的經(jīng)歷,大家就知道了。
我有位朋友,咱們就叫他小白哥吧。
小白哥剛大學(xué)畢業(yè)那會(huì)兒,想轉(zhuǎn)行做 Python 數(shù)據(jù)分析,自學(xué)了一段時(shí)間,就去面試了。
只不過,在頭一次面試中他很快就被淘汰了。
為什么呢?請大家看下他寫的代碼。
1import pandas as pd
2
3# 讀取 Excel 文件中的數(shù)據(jù)
4wenjian = 'shuju.xlsx'
5shuju = pd.read_excel(wenjian, sheet_name='Sheet1')
6
7# 顯示前五行數(shù)據(jù)
8print(shuju.head())
9
10# 處理缺失值
11quchuqueshizhi = shuju.dropna()
12
13# 顯示處理后的數(shù)據(jù)
14print(quchuqueshizhi.head())
咱也不多寫了,就說面試官一看他那代碼,把他給 pass 了。
小白哥還追著問面試官問為啥啊,我這 Pandas 用得挺好的呀,數(shù)據(jù)都出來了,也統(tǒng)計(jì)對(duì)了。
面試官笑了一下,告訴他,就沖你這命名方式,我就能看出你的進(jìn)步空間還很大,繼續(xù)努力吧,我看好你。
要知道,專業(yè)且規(guī)范的標(biāo)識(shí)命名能體現(xiàn)出一位開發(fā)者的基本素養(yǎng),也是一個(gè)開發(fā)團(tuán)隊(duì)協(xié)作的重要基礎(chǔ)。
如果連命名規(guī)范都做不好,在面試時(shí)可就會(huì)貽笑大方啦。
廢話不多說,我盡量以最簡潔清晰的方式,以給函數(shù)命名為例,給大家介紹一下 Python 中給標(biāo)識(shí)符命名的路數(shù)應(yīng)該是怎樣的。
注:Python 代碼風(fēng)格指南(https://peps.python.org/pep-0008/),即 PEP 8,包含更多命名規(guī)范相關(guān)內(nèi)容,有興趣的朋友可以去看一下。
標(biāo)識(shí)符命名的一些基本規(guī)則
Python 的標(biāo)識(shí)符包括變量、常量、函數(shù)、類、類的方法、類的屬性等。標(biāo)識(shí)符的命名規(guī)則主要有以下幾點(diǎn)。
- 要遵循 Python 命名慣例 ~ PEP8。
- 標(biāo)識(shí)符的名稱可以使用大小寫英文字母、0~9、下劃線等字符。
- 標(biāo)識(shí)符的名稱不能以數(shù)字開頭。
- 標(biāo)識(shí)符的名稱支持使用中文、日文等 Unicode 字符,但為了代碼易讀、易懂,不推薦使用。
- 標(biāo)識(shí)符的名稱最好只使用 ASCII 中的字符,讓代碼更好讀。
- 標(biāo)識(shí)符的名稱要清晰易懂,容易理解才能易于維護(hù)。
- 除非團(tuán)隊(duì)約定或行內(nèi)約定俗成,不要使用單個(gè)字母或英文單詞簡寫命名。
- 不要使用拼音命名。
函數(shù)命名的一些基本規(guī)則
- 函數(shù)名應(yīng)清晰、簡潔地說明函數(shù)要執(zhí)行的操作。如,read()。
- 函數(shù)名應(yīng)使用英文的動(dòng)詞或以動(dòng)詞開頭的多個(gè)單詞。如,read_excel()。
- 函數(shù)名要使用小寫字母,如 find()。
- 函數(shù)命名要遵循蛇形命名法。即,如果在函數(shù)名中包含多個(gè)單詞,則要使用下劃線分隔單詞。如,read_data_for_groupby()。
- 蛇形命名法是 PEP 8 中函數(shù)命名的首選方法。
有效的函數(shù)名
- find(),有效。
- user_name(),有效,但不推薦,因?yàn)闆]有表現(xiàn)出函數(shù)要執(zhí)行的動(dòng)作。
- get_99_user_name(),有效。
- _get_users(),可以以下劃線為開頭。
- 獲取用戶名(),Unicode 中的字符是有效的,但不推薦使用。
- hello?world(),? 作為 Unicode 中的標(biāo)點(diǎn)符號(hào)是有效的,但不推薦使用。
無效命名
- 10_users(),不能以數(shù)字開頭。
- save_success!(),除了下劃線,不允許使用嘆號(hào)、問號(hào)等其他 ASCII 標(biāo)點(diǎn)符號(hào)。
包含下劃線的命名法
- 當(dāng)函數(shù)名以單下劃線開頭時(shí),如 _get_users(),表示這個(gè)函數(shù)是內(nèi)部的,不能在模塊外部使用。
- 當(dāng)函數(shù)名以單下劃線結(jié)尾時(shí),可以避免你的函數(shù)名與 Python 內(nèi)置函數(shù)名或關(guān)鍵字發(fā)生沖突。如 import_(),可以避免與關(guān)鍵字 import 沖突, max_() 可以避免與內(nèi)置函數(shù) max() 沖突。
- 當(dāng)函數(shù)名以雙下劃線開頭時(shí),主要用于類中的方法或?qū)傩裕脖环Q為名稱修飾。Python 解釋器會(huì)修改使用這種命名方式定義類的屬性或方法的名稱,不能在類之外,甚至在子類中訪問該命名法定義的方法或?qū)傩浴_@個(gè)知識(shí)點(diǎn)屬于類的內(nèi)容,不在此贅述。
- 以雙下劃線開頭和結(jié)尾的命名法被稱為 dunder 命名法,dunder 是 double underscore 的簡寫。在 Python 中這種方式也叫魔術(shù)方法,這種命名法主要用于定義類的方法和變量,示例如下。
1class UserInfo:
2 def __init__(self, id_number, username):
3 self.id_number = id_number
4 self.username = username
5
6 def __repr__(self):
7 return (
8 f"{type(self).__name__}({self.id_number}, {self.username})"
9 )
在 UserInfo 類中就包含了兩個(gè)魔術(shù)方法。
- .__init__() 在創(chuàng)建類的實(shí)例時(shí)被調(diào)用,用于初始化對(duì)象。
- .__repr__() 定義對(duì)象的字符串表示,包括類名及其參數(shù)的信息。
Python 內(nèi)置的魔術(shù)方法很多,以后會(huì)有專門的文章介紹。
現(xiàn)在你只需要記住 dunder 命名法主要是用于 Python 內(nèi)置的方法,自定義方法時(shí)應(yīng)避免這種命名方式。
函數(shù)名要清晰易懂
代碼清晰、易懂是成熟開發(fā)者的重要標(biāo)志。那么,如何才能起一個(gè)可讀性強(qiáng)的函數(shù)名呢?
例如,要編寫獲取單詞首字母的函數(shù)。
如果函數(shù)名如下所示,則既難理解該函數(shù)的目的,也容易引起混淆。
1def init(n):
2 return " ".join(f"{i[0]}." for i in n.split())
init 是 initial 的簡寫形式, 即首字母的意思,但它也有初始化的意思。
如果使用簡寫形式,既容易與 __init__() 混淆,還可能會(huì)被誤解為初始化。
因此,在起函數(shù)名時(shí),盡量不要使用英文簡寫。
當(dāng)然,更不要使用漢語拼音和單個(gè)字母。
那這個(gè)名字應(yīng)該怎么起好呢?我們可以根據(jù)函數(shù)的功能 ~ “獲取首字母”,起一個(gè)直觀的名字。如 get_initials(),這個(gè)名字就清晰了。
當(dāng)然也可以加入?yún)?shù)名和介詞,如 get_initials_from(fullname),這樣是不是就更直觀了?
大家不要害怕函數(shù)名太長會(huì)增加輸入的負(fù)擔(dān),現(xiàn)代 IDE 都支持代碼自動(dòng)補(bǔ)全,可以幫你快速輸入較長的名稱。
但也不要矯枉過正,還是要避免給函數(shù)起過長的名字。這就需要你折中取舍了,不過不用擔(dān)心,只要遵循本文的原則,你很快就會(huì)熟練起來的。
方法的命名慣例
方法(method)是什么?越是簡單的名詞越難以理解,我之前就搞不明白方法與函數(shù)的區(qū)別。
其實(shí),方法和函數(shù)沒有什么本質(zhì)上的區(qū)別,它只是在類中定義的函數(shù),約定俗成地把它叫作“方法”罷了。
因此,在命名方法時(shí)也要遵循函數(shù)的命名慣例,使用蛇形命名法,并應(yīng)以動(dòng)詞或動(dòng)詞開頭的多個(gè)單詞命名。如 check_user_age() 或 show_use_info()。
如果要在類定義某個(gè)方法,但又不想將其作為類的接口,并且不需要調(diào)用類中的這個(gè)方法時(shí),則可以在方法名稱前添加單個(gè)下劃線,如 _check_user_age()。
這種方式不能阻止直接調(diào)用該方法,示例如下。
1class UserInfo:
2 def _check_user_age(self, age):
3 return self.age >= age
在 REPL 中輸入如下代碼,可以看到返回的內(nèi)容。
1>>> from user_info import UserInfo
2>>> user = UserInfo("Johnson", 50)
3>>> user._check_user_age(25)
4False
以下劃線開頭的 _check_user_age() 方法不會(huì)在 VSCode 等 IDE 的代碼自動(dòng)補(bǔ)全提示中顯示。但像在 REPL 中一樣,我們?nèi)钥梢暂斎氩⒄{(diào)用該方法。
到這里基本上就講完了函數(shù)名/方法名的命名規(guī)則了。下面再簡單介紹一下命名函數(shù)與命名其他標(biāo)識(shí)符的異同之處。
函數(shù)與其他標(biāo)識(shí)符命名規(guī)則的相同點(diǎn)
- 都不能以數(shù)字開頭。
- 都不能有除下劃線以外的 ASCII 標(biāo)點(diǎn)符號(hào)。
- 都應(yīng)盡量避免使用單個(gè)字母或英文簡寫命名,除非是大家約定俗成的簡寫方式。
- 變量也要使用小寫字母命名。
- 變量也要使用蛇形命名法。
函數(shù)與其他標(biāo)識(shí)符命名規(guī)則的不同點(diǎn)
- 類使用首字母大寫的方式命名。
- 類不使用蛇形命名法,而是使用大駝峰命名法,即所有首字母都大寫,如,UserInfor。
- 還有一個(gè)是常量,常量也使用大寫字母命名,但使用下劃線分割多個(gè)單詞。如,TIME_LIMIT。
結(jié)語
本文主要介紹了以下知識(shí)點(diǎn)。
- Python 的代碼風(fēng)格指南(PEP8)是 Python 好好學(xué)習(xí)的參考手冊,這里介紹一個(gè)支持庫,叫 autopep8,大家可以安裝使用。
- Python 標(biāo)識(shí)符的命名基本規(guī)則。
- Python 函數(shù)/方法命名的基本規(guī)則與示例。
- 下劃線在標(biāo)識(shí)符命名中的特殊作用。
- 函數(shù)與其他標(biāo)識(shí)符的命名的異同。
總之,Python 標(biāo)識(shí)符的命名很重要,既涉及代碼可讀性,也涉及開發(fā)團(tuán)隊(duì)的協(xié)作,大家一定要規(guī)范命名。