如何寫出優雅的程式碼?

背景介紹

以下這些程式碼片段是我工作多年,總結的一些如何寫出漂亮程式碼的方法,歡迎小夥伴前來借鑒或者討論。
參考書籍《程式碼整潔之道》,《寫好Python程式碼的91個建議》

正文開始

程式碼段1

def get_enviroment(self, environment_id: int = None, environment_name: str = ""):
    if environment_id: 
        environment = self.session.query(
            models.Environment).filter_by(
                id=environment_id).first() 
    else: 
        environment = self.session.query(
            models.Environment).filter_by( 
                name=environment_name).first() 

    return environment 

這段程式碼的意思是,我們從調用方獲取參數,如果是拿到了environment_id,我們就執行if程式碼塊,如果是我們拿到了environment_name, 我們就執行else程式碼塊。
不知道大家看到這段程式碼,有沒有發現什麼問題?


⏱️一分鐘思考時間。。。


在這段程式碼中,我們在進行session.query時,多處使用了重複的程式碼,這樣雖然沒有任何程式上的問題,但是看起來非常不優雅。
於是我修改之後,如下

def get_enviroment(self, environment_id: int = None, environment_name: str = ""): 
    condition = {'id': environment_id} if environment_id else {'name': environment_name} 

    return self.session.query(models.Environment).filter_by(**condition).first() 

思考

通過分析發現,我們可以將要查詢的變數組裝成一個字典形式,然後在session.query中使用雙星號解包使用。
這樣很巧妙的去掉了冗餘不好看的程式碼結構。

程式碼段2

if testcase_id and account_type:
    stmt = (
        select(
            models.Accounts).where(
            exists_testcase_id,
            exists_account_type,
            exists_account_status))
elif testcase_id:
    stmt = (
        select(
            models.Accounts).where(
            exists_testcase_id,
            exists_account_status))
elif account_type:
    stmt = (
        select(
            models.Accounts).where(
            exists_account_type,
            exists_account_status))
elif status:
    stmt = (
        select(
            models.Accounts).where(exists_account_status))
else:
    stmt = (select(models.Accounts))
return self.session.execute(stmt).all()

在這段程式碼中,我們最終是通過參數的組合來查詢Accounts數據,在這個函數種我們接受了多個參數,testcase_id,account_type,status。這幾個參數又可以產生多種組合。
如果是按照上面的編碼方式,那麼我們寫出來的程式碼很長而且冗餘。
那麼如何重構它呢???


⏱️一分鐘思考時間。。。


conditions = []

if testcase_id:
    conditions.append(models.Accounts.testcase_object.has(
        models.Testcase.testcase_id == testcase_id))
if account_type:
    conditions.append(models.Accounts.account_type_object.has(
        models.AccountType.name == account_type))
if status:
    conditions.append(models.Accounts.status == status)

stmt = (select(models.Accounts).where(*conditions))

return self.session.execute(stmt).all()

思考

我們通過分析發現,由於多個參數存在多種組合,那麼我們首先需要一個列表來存放這些查詢條件,然後通過if-else來添加要查詢的條件放入列表中。
最後在倒第二行的時候,統一解包。
這樣重構的好處就是,我們不需要再去關注他們有多少種組合的情況,我們只需把要查詢的條件,統一存放起來。然後再進行查詢操作。