8. __init__函數內不可以使用return語句
Python規定__init__函數只能返回None,否則會引起TypeError
9. 在try…except…finally中return
- try和except中return語句設定的返回值,可以在finally塊中被修改;
- 實踐中不要在finally中使用return,這是一種不好的代碼,容易讓人產生疑惑。finally塊主要用於進行清理工作。
Python札記7:在try...except...finally中return
不論try
語句塊中發生了什么異常,finally
語句塊中的代碼都會被執行。所以我們通常在finally
語句塊中做清理工作,例如關閉文件等等
請看下面的代碼,輸出是什么呢?
def f(): try: return 1 finally: print("hehe") print(f())
finally
塊中的代碼必定執行,所以輸出如下:
也就是說,雖然try
中有return
語句,但是退出try...finally
塊之前,也一定會執行finally
塊中的語句。
10. os.path的abspath()和realpath()區別
- os.path.abspath 返回目標地址,會處理.,..等相對路徑,不處理軟連接和快捷方式
- os.path.realpath 返回的是使用軟鏈的真實地址,它能在所有的平台上對所有別名、快捷方式以及符號鏈接進行一致地解析。
# 特殊的文件名,比如 “..” 會被移除,這樣輸入在驗證之前會被簡化成其標准形式。
當使用標准形式的文件路徑來做驗證時,攻擊者將無法使用 ../ 序列來跳出特定目錄
11. python中and與or的邏輯
首先,‘and’、‘or’和‘not’的優先級是not>and>or。
其次,邏輯操作符and 和or 也稱作短路操作符(short-circuitlogic)或者惰性求值(lazy evaluation):它們的參數從左向右解析,一旦結果可以確定就停止。例如,如果A 和C 為真而B 為假, A and B and C 不會解析C 。作用於一個普通的非邏輯值時,短路操作符的返回值通常是最后一個變量。因此,邏輯運算符的理解也與C語言中不同
a = {1, 2, 3} and {4, 5, 6} b = {1, 2, 3} or {4, 5, 6} print(a) # {4, 5, 6} print(b) # {1, 2, 3}
其實python中and並不是直接返回True/False,而是返回比較的值,具體如下邏輯:
and:停止的目標為False, 如果有True,一直往下找,直到返回最后一個或者第一個False
or: 停止的目標為True,如果有False,一直往下找,直到返回最后一個或者第一個True
12. 字符串,bool,序列對象等都可以比較
1.2 > True # True 1 > True # False bool('0') # True
字符串也好,列表也好,都是可迭代對象。先比較兩個對象的第0個元素,大小關系即為對象的大小關系(字典序),如果相等則繼續比較后續元素,先終止迭代的認為是小的。序列對象通常可以與相同序列類型的其他對象比較。
[1,5]<[3,4,6] # True [1,4,[5,6]]<[3,4,6] # True [3,4,[5,6]]<[3,4,6] # TypeError: '<' not supported between instances of 'list' and 'int'
13. 字符串格式化
https://blog.csdn.net/qq_27825451/article/details/105652244
14. @classmethod與@staticmethod
Python中的類也是一個普通對象,如果需要直接使用這個類,例如將類作為參數傳遞到其他函數中,又希望在實例化這個類之前就能提供某些功能,那么最簡單的辦法就是使用classmethod和staticmethod。這兩者的區別在於在存在類的繼承的情況下對多態的支持不同。
類方法的作用:(不依賴於對象)
因為只能訪問類屬性和類方法,所以,可以在對象創建之前如果需要做一些功能(動作),就可以放在類方法中
私有屬性只能通過類方法,在類內部進行訪問
靜態方法:很類似類方法
1.需要裝飾器@staticmethod
2.靜態方法是無需傳遞參數(如,cls,self)
3.靜態方法里面也只能訪問類的屬性和方法,而對象的屬性和方法是無法訪問的(即,用self.xx訪問屬性和訪問方法是不可以的)
4.加載時機同類方法,即在對象還沒有創建時,就已經加載了
class Spam(object): numInstances = 0 @staticmethod def count(): Spam.numInstances += 1 def __init__(self): self.count() class Sub(Spam): numInstances = 0 class Other(Spam): numInstances = 0 x = Spam() y1, y2 = Sub(), Sub() z1, z2, z3 = Other(), Other(), Other() # 對象調用 print(x.numInstances, y1.numInstances, z1.numInstances) # 類調用 print(Spam.numInstances, Sub.numInstances, Other.numInstances)
總共六次加載對象,靜態方法在對象還沒有創建之前就已經加載了了,因此x.numInstances=6,而另外兩個是Spam的子類,創建對象后,又執行了y1.numInstances,y2.numInstances,因此,y1.numInstances=0,y2.numInstances=0
Spam.numInstances, Sub.numInstances, Other.numInstances分別是訪問它們類的屬性
https://www.cnblogs.com/GumpYan/p/12381705.html
15. 防范會話固定,應采取以下步驟:
- 登錄時,使當前會話無效,並建立一個新的會話。
- 不要接受以GET 或POST參數方式提交的會話 ID,包括隱藏的表單變量。
- 在所有cookie上設置HttpOnly屬性為true,以防范腳本讀取cookie內容。
- 在所有cookie上將Secure(安全)屬性設置為true,使其只能通過TLS連接發送。
- 在會話cookie上設置合理的失效日期。
15.1 系統環境變量是屬於“不可信數據”,直接使用不可信數據可能會引入安全風險
import os home = os.getenv('APPHOME') cmd = os.path.join(home, INITCMD) os.system(cmd)
其中環境變量APPHOME對應的路徑是可修改的,直接使用會造成安全風險。
16. shell命令
Subprocess安全
subprocess模塊的用法, run/Popen/call/check_call/check_output 在使用時指定shell參數為False時,都會存在命令注入缺陷。(第一個參數禁止使用cmd/bash)
切記第1個參數中的list列表的第一個元素不允許是“bash”、“cmd”、“/bin/sh”,第二個元素不允許是“-c”;只有滿足了這兩個前提條件,參數shell=True情況才是安全的。
subprocess模塊的用法, Popen/call/check_call/check_output 在使用時指定shell參數為False時,都會存在命令注入缺陷。(第一個參數禁止使用cmd/bash,第二個元素不允許是“-c”)。如果不可避免的要設置shell為true,應將命令作為單一字符串傳遞,並使用shelx.quote()手動轉義所有shell元字符。
Python安全編程規范V2.1
規則 1.8 禁止使用subprocess模塊中的 shell=True選項
subprocess模塊中的 shell=Flase場景的第1個參數為什么不能是cmd/bash/sh等系統命令
17. 隨機數的安全
根據安全規范6.5:
os.urandom在windows系統中生成的隨機數是安全的,在linux系統環境中生成的隨機數不安全。
random模塊生成的是偽隨機數,不能應用於安全加密目的的應用中
安全隨機數可以使用:/dev/random,Python3.6以上的secrets模塊
18. 全局常量用全大寫,全局變量用小寫
19. 避免直接使用dict[key]的方式從字典中獲取value
如果一定要使用,需要注意當key not in dict時的異常捕獲和處理。應始終使用get,即dict.get(key),而不是dict[key]
20. 避免變量在其生命周期內的對象類型發生變化。
如:
items = 'a,b,c,d' # 字符串 items = items.split(',') # 變更為列表
21. 驗證路徑之前應該先將其標准化
使用os.path.realpath('test')
而非os.path.abspath('test')
。 Path().resolve()
好像類似。
22. Server端發起網絡請求前要驗證是否存在SSRF漏洞。
SSRF(Server-SideRequest Forgery, 服務端請求偽造)
應該先對url做ssrf校驗
url = sys.argv[1] try: info = urllib.request.urlopen(url).info() print(info) except urllib.error.URLError as e: print(e)
規避SSRF漏洞的思路:
- 解析目標URL,獲取其Host
- 解析Host,獲取Host指向的IP地址
- 檢查IP地址是否為內網IP
- 請求URL
- 如果有跳轉,拿出跳轉URL,回到第1步循環此過程
23. 禁止使用tempfile.mktemp創建臨時文件
使用tempfile.mkstemp()
、NamedTemporaryFile()
、mkdtemp()
, 而非tempfile.mktemp()
24. 禁止使用私有或者弱加密算法
比如DES,MD5等
25. 使用ssl.SSLSocket代替socket.Socket來進行安全數據交互
26. 代碼發布前務必刪除開發者信息及包含開發者信息的注釋內容
Python代碼中的注釋不能體現的信息有:工號、姓名、部門、郵箱等。
27. 在except分支里面的raise可以不帶異常
28. 防范會話固定的最佳實踐
用戶成功登陸后,應立即使原有會話ID失效,並建立一個新的會話ID。
29. 關於跨站腳本的一些敘述
√假定所有輸入都是不可信的
×應該對所有不可信數據進行十六進制編碼,然后給字符串兩邊加等號
×JavaScrip在訪問cookie內容時,如果數據已使用\字符進行轉義,JavaScrip應該被視為可信的
√向網頁內容注入惡意標記或腳本,會竊取cookie、劫持會話或將頁面重定向到惡意網址
30. 常用來維持對象狀態一致性的手段
- 優化代碼邏輯,避免修改對象的狀態
- 調整邏輯順序,使可能發生異常的代碼在對象被修改前執行
- 當業務操作失敗時,進行回滾
- 對一個臨時的副本對象進行所需的操作,直到成功完成這些操作后,才把更新提交到原始的對象
- 對參數進行校驗,提前避免異常
31. 避免SQL注入的推薦做法
使用預處理語句或者參數化查詢創建動態查詢
32. 最安全的序列化格式:JSON
33. pdb基本用法
使用pdb進行調試:
pdb 是 python 自帶的一個包,為 python 程序提供了一種交互的源代碼調試功能,主要特性包括設置斷點、單步調試、進入函數調試、查看當前代碼、查看棧片段、動態改變變量的值等。pdb 提供了一些常用的調試命令,詳情見表
下面結合具體的例子說明:
import pdb a = "aaa" pdb.set_trace() b = "bbb" c = "ccc" final = a + b + c print(final)

退出 debug:使用 quit 或者 q 可以退出當前的 debug,但是 quit 會以一種非常粗魯的方式退出程序,其結果是直接 crash。
輸入了q之后:

33.1 pdb有2種用法:
非侵入式方法(不用額外修改源代碼,在命令行下直接運行就能調試)
python3 -m pdb filename.py
侵入式方法(需要在被調試的代碼中添加一行代碼然后再正常運行代碼)
import pdb;pdb.set_trace()
當你在命令行看到下面這個提示符時,說明已經正確打開了pdb
(Pdb)
然后就可以開始輸入pdb命令了,下面是pdb的常用命令
34. 哈希表的查找
哈希表:存放鍵值(地址)和數值的存儲結構
哈希函數:把數值映射(幫這個數值找一個地址)到地址的函數
為了能有效運用查找技術,必須解決的問題是:構造一個好的哈希函數,確定一個解決沖突的方法
- 哈希函數的構造方法:
- 直接定址法:直接以關鍵字(本身數值)或關鍵字加上某個常量作為地址
好處:計算簡單
缺點:關鍵字不連續的時候會造成內存浪費()就比如說:12跟134 - 除留余數法:關鍵字除以一個整數p所得余數作為哈希地址(p小於等於哈希表長度m,但p最好小於m的素數,這種效果最好)
- 數字分析法:提取關鍵字中取值較均勻的數字作為哈希地址
- 直接定址法:直接以關鍵字(本身數值)或關鍵字加上某個常量作為地址
- 哈希沖突的解決方法
- 開放定址法:就是這個位置用不了,那我就去找用得了的位置)
然后找用空閑位置的方法又有: - 線性探測法:就是這個位置用不了,那就從后面的位置依次尋找空閑的位置)
缺點:容易發生堆聚現象;堆聚就是存入哈希表的若干個同義詞(產生地址沖突的數據)在表中連成一片,占用了其他關鍵字的映射位置。 - 平方探測法
- 拉鏈法:把產生沖突的位置放在一個單鏈表里)
- 開放定址法:就是這個位置用不了,那我就去找用得了的位置)
例子1:
例子2:
例子3:
30%7=2
14%7=0
40%7=5
63%7=0
22%7=1
5%7=5
34.1 二次探測再散列處理
哈希表有14個桶,h(key)=key%11,現有18,37,55,61,79,如果用二次探測再散列處理沖突,則39位於第(D)個桶內。
A 6 B 8 C 4 D 10
解析:
18,37,55,61,79 和11除余分別是: 7 4 0 6 2. 沒有沖突,分別放入對應桶中
39%11=6, 被占用, 按照+1, -1, +4, -4, +9, -9... 的規則探測
(6 +1)%11 = 7 被占用
(6 - 1)%11 = 5 沒被占用,放入5號桶
(6 +4)%11=10放入10號桶