一、坑坑坑
1.1 並行編程坑
- mutiproccesssing多進程不能共享主進程的全局變量、甚至常量。如果需要共享常量可以直接傳參。如果是要使用共享變量,只能使用mutiproccesssing.Manager()下面的共享變量工具了。
1.2 全局變量坑
- python全局變量不能在函數內被修改,除非再用global關鍵字聲明。
1.3 中文編碼坑
- 考慮舊版本兼容性,代碼中含中文的話,文件頭聲明
# coding:utf-8
1.4 Python類成員變量初始化坑
-
危險操作: 在init()方法外直接定義列表或字典這類可變對象,如下NODE類中的children,這樣實例化的所有對象的children都會指向同一地址(類似全局變量),導致修改一個對象的children列表,其他NODE對象的children列表都會一起改變,可通過id()函數檢測變量地址。但使用該方法定義int或字符串這類不可變對象時時安全的。
## 危險1:init方法外定義可變類型變量 class NODE: children = [] def __init__(self): pass ## 危險2:init方法內定義但設置了函數默認參數 class NODE: def __init__(self, children=[1,2]): self.children = children
-
安全的初始化操作如下,建議所有變量初始化在__init()__方法下進行,且可變類型的變量不可以設置默認函數參數,否則也會導致共享變量。
# 安全定義 class NODE: def __init__(self): self.children = []
二、大道至簡Pythonic
自己總結的一些代碼規範, 歡迎補充和意見:
- 參數分離 如果有較多的常量參數設置,獨立一個settings.py文件出來,如
setting.version
, 如果參數較少,在當前文件前面聲明即可。 - 鏈式比較
points[3][0] == points[0][0] < points[1][0] == points[2][0]
, 有一個條件不成立則返回False - 條件賦值
a = b if expr else c
- 函數式編程 熟練運用常用的函數式編程,代碼可讀性和coding效率可以直接蹭蹭上漲一個段位啊,spark分佈式開發中有很多共同之處,包括但不限於:
filter() # 按條件過濾, 當你想從列表/字符串中按條件移除元素時是否感覺很難受? sorted() # 排序,任何自定義的元素類型 map() # 1 to 1 映射 reduce() # 迭代
- generator 節省內存提效率利器
- 封裝!封裝! 封裝是很重要的編程技巧,很多語言都適用,中小型項目中(我也沒寫過啥大項目),要注意類的封裝、模塊的封裝、函數的封裝。積極運用下劃線
_
區分私有共有資源。 - 註釋 合理的封裝加上註釋,完美!
- 日誌、進度條 對提高程序使用體驗來說很重要的好伐
- 下劃線 使用下劃線來接收不想做處理的返回值。例如
_, data = getData()
- f-string 別再傻傻的用以前的格式化字符串了,python3.6之後,你可以這麼玩:
name = geekhch
now_time = time.strftime("%m %d", time.localtime())
msg = f'hello, {name}, today is {now_time}' # 要注意單引號雙引號匹配
三、代碼規範
任何代碼風格中,命名規範都是最重要的point之一吧, 一般來說,只要自己的代碼風格統一即可,但每種語言都有約定俗成的規範。 !! 如果命名不能準確表達含義,一定要加註釋,多花幾秒的時間,潛力無限 !!
- 類命名- 大駝峯
- 普通函數命名- 全小寫、字母開頭、下劃線分割
- 私有函數命名- 以單個下劃線開頭
- 變量命名- 普通變量與函數規則相同
status_now
, - 全局變量常量- 全大寫,下劃線分割單詞,如
NETWORK_STATUS
- 等號對齊- 多個等式上下排列, 儘量對齊等號
四、高級操作
知識點先碼着,有空再補教程
- 函數式編程
- 裝飾器
- 並行編程mutiproccessing
- 註解@符號
五、一些感動到哭的python工具包
- loguru 日誌工具,一行導入,免配置使用,彩色日誌。
from loguru import log
、logger.add(filepath)
- tqdm 進度條工具
from tqdm import tqdm