寫程式碼不那麽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(1, 4)] for i in range(5, 10)]
改成如下迴圈函式是否更好?
defgenerate_nested_list(start_i, end_i):
nested_list = []
for i in range(start_i, end_i):
sublist = []
for j in range(1, 4):
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+小夥伴一起學習!