當前位置: 妍妍網 > 碼農

如何激怒一位Python愛好者?

2024-03-18碼農

寫程式碼不那麽pythonic風格的,多多少少都會讓人有點難受。

什麽是pythonic呢?簡而言之,這是一種寫程式碼時遵守的規範,主打簡潔、清晰、可讀性高,符合PEP 8(Python程式碼樣式指南)約定的模式。

Python社群發展幾十年,已經沈澱出一套更加科學規範的程式碼書寫法則,該踩的坑都幫你踩過了,按這個來基本不會出什麽錯。

下面舉幾個不那麽pythonic的程式碼案例,雖然不會出錯,但十分不建議這樣寫。

1、函式、變量命名無意義、不規範

很多人圖省事,使用a、aa、bbb這樣無意義的變量名、函式名,這樣在編程中會大大降低程式碼的可讀性,也影響程式碼品質。

defa(revenue, cost):
"""
計算銷售利潤率。
:param revenue: 銷售額(或總收入)
:param cost: 成本
:return: 銷售利潤率(以百分比表示)
"""

if revenue <= 0or cost < 0:
return"錯誤:銷售額必須大於0,成本不能為負數。"
aa = revenue - cost
bbb = (aa / revenue) * 100
return bbb

更有初學者使用中文來作為變量名,雖然在語法上是允許的,但會引起歧義,不符合程式碼規範

年齡 = 30
名字 = "張三"
print("{}的年齡是{}".format(名字,年齡))

2、不善於使用函式和類,重復寫程式碼

Python是鼓勵用函式和類去封裝一些重復用的功能,這樣能增加程式碼的可讀性,也減少不必要的勞動,但一些人就是喜歡寫很長的程式碼,導致看著很冗余。

在Python中大家可以把一個復雜的功能,用多個函式去分解,一個函式程式碼行數最好不要超過十行,如果確實需要很多程式碼,那就進行分解,多寫幾個函式來實作。

比如以下的函式,用來實作csv檔的讀取、行去重、空值剔除、保存等功能。

import csv
defprocess_csv(input_file, output_file):
"""
讀取CSV檔,去重,剔除空值,並保存到新檔。
:param input_file: 輸入的CSV檔路徑
:param output_file: 輸出的CSV檔路徑
"""

# 讀取CSV檔
with open(input_file, mode='r', newline='', encoding='utf-8'as file:
reader = csv.reader(file)
rows = [row for row in reader if row] # 剔除空行
# 去重
unique_rows = []
for row in rows:
# 將行轉換為元組以用於集合去重
unique_rows.append(tuple(row))
# 剔除空值
processed_rows = [[cell for cell in row if cell] for row in unique_rows]
# 轉換回列表以寫入CSV檔
processed_rows = [[str(cell) for cell in row] for row in processed_rows]
# 寫入新的CSV檔
with open(output_file, mode='w', newline='', encoding='utf-8'as file:
writer = csv.writer(file)
writer.writerows(processed_rows) 



當你看到這個函式,是不是覺得有點冗長,一個函式實作了四個功能,不易閱讀也不利於重復利用。

如果把它拆分成四段函式,分別實作讀取、行去重、空值剔除、保存這四個功能,就會更加清晰。

import csv
defread_csv(file_path):
"""
讀取CSV檔並返回行的列表。
:param file_path: CSV檔路徑
:return: CSV檔行的列表
"""

with open(file_path, mode='r', newline='', encoding='utf-8'as file:
reader = csv.reader(file)
return [row for row in reader if row] # 剔除空行
defremove_duplicates(rows):
"""
去除行列表中的重復行。
:param rows: 行的列表
:return: 去重後的行列表
"""

return list(set(tuple(row) for row in rows))
defremove_empty_values(rows):
"""
從行列表中剔除含有空值的行。
:param rows: 行的列表
:return: 剔除空值後的行列表
"""

return [[cell for cell in row if cell] for row in rows]
defwrite_csv(file_path, rows):
"""
將行列表寫入CSV檔。
:param file_path: CSV檔路徑
:param rows: 要寫入的行列表
"""

with open(file_path, mode='w', newline='', encoding='utf-8'as file:
writer = csv.writer(file)
writer.writerows(rows)


3、使用很復雜的列表推導式,較難閱讀

列表推導式可以簡化列表的建立,既實用還能讓程式碼更加美觀,但列表推導式只適合建立邏輯簡單的列表,對於很復雜且程式碼量大的列表,是不建議用列表推導式的,比如以下案例。

nested_list = [[(i * j, i + j, i - j) for j in range(14)] for i in range(510)]

改成如下迴圈函式是否更好?

defgenerate_nested_list(start_i, end_i):
nested_list = []
for i in range(start_i, end_i):
sublist = []
for j in range(14):
sublist.append((i * j, i + j, i - j))
nested_list.append(sublist)
return nested_list

4、程式碼行特別長,也很難閱讀

一般Python程式碼行長度最好不要超過79,vscode和pycharm等編輯器裏都有程式碼長度指引線,寫程式碼時遇到它就是提示你要換行了。

連續程式碼(一行程式碼很長,需要分在多行寫)中被裹著的程式碼(可能被 (), [], {} 包裹)應該垂直(左)對齊。

deflong_function_name(
var_one, var_two, var_three,
var_four)
:

print(var_one)

其實還有很多pythonic風格的規範,需要大家註意,建議按照約定俗成的方法去寫,第一原則是可讀性強,可讀性強,可讀性強。

加入知識星球【我們談論數據科學】

600+小夥伴一起學習!