https://nmap.org/
公司實驗室的機器 IP有時候飄來飄去,這時候就可以靠 nmap來找到需要的機器。
掃描指定機器的常用埠
掃描子網路 (192.168.1.0 to 192.168.1.255)
掃描指定的埠
偵測每個埠上運行的服務
掃描子網路下所有 port 22的狀態為 open的機器
- -T4 加速掃描速度
- --open 只列出狀態為 open的 port
- --oG - 輸出grepable的格式到console
https://nmap.org/
公司實驗室的機器 IP有時候飄來飄去,這時候就可以靠 nmap來找到需要的機器。
官方網址:
https://learn.microsoft.com/en-us/windows/core-utils/overview
https://github.com/microsoft/coreutils
Coreutils可以在原生Windows上跑 UNIX風格命令列工具,由 Microsoft自己維護。
安裝:
能用的命令可以參考:
https://learn.microsoft.com/en-us/windows/core-utils/commands
記錄一些常用的 Linux指令或工具
將字串或變數輸出到終端機的指令
輸出字串
輸出變數
concatenate,主要功能為將檔案內容輸出到終端機或另一個檔案
| cat command options | |
| -n, --number | 輸出行數。 |
輸出 a.txt的檔案內容
將 a.txt和 b.txt的檔案內容串接輸出到終端機
將 a.txt和 b.txt的檔案內容串接寫到新檔案 ab.txt中
將 b.txt的檔案內容串接寫到 a.txt後
print working directory,輸出當前終端機的目錄
list,用來輸出目錄的內容或資訊
| ls command options | |
| -l | Long format。顯示詳細資訊。 |
| -a | All file。顯示隱藏檔案。 |
| -h | Human-readable。將檔案容量大小顯示為人類可讀格式。 |
| -t | Sort by time。以修改時間來將檔案排序,由新到舊。 |
| -R | Recursive。列出所有包含子目錄中的檔案。 |
change directory,切換目錄
切換到家目錄
切換到根目錄
切換到上一層目錄
切換到上一次所在的目錄
使用絕對路徑切換目錄
切換到當前目錄下的子目錄
make directory,建立目錄
在當前目錄下建立目錄
建立多個層級的目錄
建立目錄並設定權限
建立多個目錄
move,用來重新命名或移動檔案和目錄
| mv command options | |
| -i | interactive。檔案覆蓋前跳出提示。 |
| -f | force。強制覆蓋已存在的檔案。 |
| -n | no-clobber。不覆蓋已存在的檔案。 |
| -u | update。當來源檔案較新或是目的檔案不存在才移動。 |
| -v | verbose。顯示命令執行詳細過程。 |
移動檔案
重新命名檔案
copy,複製檔案和目錄
| cp command options | |
| -r | recursive。遞迴地複製檔案,用來複製目錄。 |
| -i | interactive。檔案覆蓋前跳出提示。 |
| -p | preserve。保留檔案的權限及時間戳。 |
| -u | update。當來源檔案較新或是目的檔案不存在才複製。 |
| -a | preserve all。遞迴地複製檔案,並且保留檔案權限及時間戳。 |
| -v | verbose。顯示命令執行詳細過程。 |
複製檔案
複製檔案到目錄
manual,用來查看命令、系統呼叫、函式庫或設定檔的使用方法。
| man 操作方法 | |
| / | 搜尋關鍵字 |
| q | 離開 |
查詢 ls的使用方法
remove,用來刪除檔案或目錄。
| cp command options | |
| -f | force。強制刪除。 |
| -r | recursive。遞迴地刪除目錄及其中的檔案。 |
| -i | interactive。刪除檔案前跳出提示。 |
| -v | verbose。顯示命令執行詳細過程。 |
刪除檔案
強制刪除目錄及其中檔案
用來建立空檔案或是更新檔案的時間戳。
建立空檔案,如果檔案存在則更新時間戳為現在。
指定更新時間,格式為 [[CC]YY]MMDDhhmm[.ss]。
參考其他檔案的時間來更新。
只更新 atime(access time)。
只更新 mtime(modify time)。
change mode。用來變更檔案或目錄的存取權限。
給予所有人讀寫及執行權限。
給予檔案擁有者所有權限,其他人讀取及執行權限。
給予檔案擁有者讀寫權限,其他人只有讀取權限。
給予所有人執行權限。
給予擁有者寫入權限。
取消群組及其他人的寫入權限。
所有人設定為只能讀取權限。
tape archive。打包及檔案壓縮工具。
| tar command options | |
| -f | 指定要處理的檔名 |
| -v | 列出每一步處理涉及的檔案資訊 |
| -x | 解開 tar檔案 |
| -z | 呼叫 gzip壓縮或解壓縮檔案。 |
| -c | 建立壓縮檔案。 |
解開tar檔案
解開tar.gz檔案
官方網址:
https://github.com/gokcehan/lf
| 最重要的命令 | |
| q | 離開 lf |
| 移動 | |
| j or [↓] | 檔案列表中往下移動 |
| k or [↑] | 檔案列表中往上移動 |
| [Ctrl] + d | 檔案列表中往下移動半頁 |
| [Ctrl] + u | 檔案列表中往上移動半頁 |
| [Ctrl] + b or [PgDn] | 檔案列表中往下移動一頁 |
| [Ctrl] + f or [PgUp] | 檔案列表中往上移動一頁 |
| h or [←] | 移動到上一層目錄 |
| l or [→] | 移動到下一層目錄,或者開啟檔案 |
| gg or [Home] | 移動到最上面的檔案 |
| G or [End] | 移動到最下面的檔案 |
| 檔案操作 | |
| gg or [Home] | 移動到最上面的檔案 |
| G or [End] | 移動到最下面的檔案 |
| [Space] | 選取目前的檔案 |
| v | 取消選取目前的檔案 |
| u | 取消所有選取的檔案 |
| y | 複製目前或者選取的檔案 |
| d | 剪下目前或者選取的檔案 |
| p | 貼上複製或剪下的檔案到當前的目錄 |
| c | 取消貼上複製或剪下的檔案 |
| 命令列 | |
| : | 輸入預設或自定義的命令 |
| $ | 在 shell下執行命令 |
| % | 在 shell下執行命令,並將ui pipe到input,output pipe到ui |
| ! | 在 shell下執行命令,並等待按鍵輸入 |
| & | 在背景執行命令 |
| 搜尋 | |
| / | 搜尋符合pattern的輸入 |
| ? | 反向搜尋符合pattern的輸入 |
| n | 下一個符合pattern的結果 |
| N | 上一個符合pattern的結果 |
| 設定 | |
| z | 更改某些選項的設定 |
| s | 更改 sortby及 info的設定 |
| 開啟 | |
| e | 開啟檔案編輯器 |
| i | 開啟 pager |
| w | 開啟 shell |
Linux
Windows
可以透過修改環境變數來更改 lf的預設指令
| 環境變數 | |
| OPENER | Windows: start Linux: xdg-open |
| EDITOR | Windows: notepad Linux: vi |
| PAGER | Windows: more Linux: less |
| SHELL | Windows: cmd Linux: sh |
官方網址:
https://github.com/yrp604/rappel
rappel提供了一個 assembly的交互式介面環境,可以在執行完指令後馬上看到暫存器狀態的變化,用來嘗試一些指令非常好用。
編譯完後可從./bin/rappel執行,Ctrl + d 退出程序:
可以透過將 .gdbinit檔案放到 home目錄下對 GDB做初始化設定。
設置斷點
執行程式
離開 gdb
顯示下一個所要執行的組合語言指令
確認當前 set disassemble-next-line的設定狀態
顯示暫存器的值
將 rax暫存器的值設為 0x1234
印出 0x402000地址的值
grep是 Linux下用來在檔案中尋找文字的工具。
| grep command options | |
| Matching Control | |
| -e PATTERNS | 指定搜尋的 pattern,可以宣告多次。 |
| -i, --ignore-case | 忽略大小寫。 |
| -v, --invert-match | 印出不符合的結果。 |
| -w | whole word only。 |
| General Output Control | |
| -c, --count | 只印出符合結果的行數。 |
| -l | 只印出符合結果的檔案名稱。 |
| -o | 只印出符合的部分。 |
| Output Line Prefix Control | |
| -h, --no-filename | 只顯示符合的結果,不顯示檔案名稱。 |
| -n, --line-number | 在符合的結果前面加上行號。 |
| Context Line Control | |
| -A NUM | 印出符合的結果後面 NUM行。 |
| -B NUM | 印出符合的結果前面 NUM行。 |
| -C NUM | 印出符合的結果前面及後面 NUM行。 |
| File and Directory Selection | |
| -r, --recursive | 尋找指定目錄下所有檔案的符合結果。 |
在 file.txt中尋找有 abcd字串的行。
在 file.txt中尋找有 abcd字串及有 efgh的行。
在 file.txt和 file2.txt中尋找有 abcd字串及有 efgh的行。
在當前目錄下的所有檔案中尋找有 abcd字串的行。
只列出當前目錄下的所有檔案中有 abcd字串的檔案名稱。
find是 Linux下用來尋找檔案及目錄的命令。
| find command options | |
| -name [pattern] | 搜尋符合 pattern的檔案。 |
| -iname [pattern] | 搜尋符合 pattern的檔案。(case insensitive) |
| -type [type] | 搜尋特定類型的檔案。-type f為只搜尋檔案,-type d為只搜尋目錄。 |
| -maxdepth [levels] | 限制最大的搜尋的目錄層數。 |
| -mindepth [levels] | 限制最小的搜尋的目錄層數。 |
| -exec [command] {} \; | 對於每個找到的檔案執行 [command],帶入 {}為找到的檔案。 |
| -delete | 移除所找到的檔案。 |
在當前目錄尋找名為 file.txt的檔案。
忽略大小寫,在當前目錄尋找名為 file.txt的檔案。(case insensitive)
在當前目錄尋找名稱結尾為 .txt的檔案
在當前目錄尋找名稱帶有 file的目錄
在當前目錄尋找名稱帶有 file的檔案
移除所有帶有 file名稱的檔案
計算用 find所找到檔案的數量
排序用 find所找到的檔案
取得找到檔案的 md5值
tmux是個 Linux下的終端機管理程式,可以在同一個終端 (terminal)下同時操作多個程式, 對於透過 SSH連線來使用機器來說非常方便。
開啟新的 tmux session
開啟名為 <session_name>新的 session
列出當前的所有的 tmux session
attach到 <session_name>的 tmux session
detach當前的 tmux session
關閉session
| tmux快捷鍵 | |
| [Ctrl]+b d | detach當前的 tmux session |
| [Ctrl]+b " | 垂直分割兩個 pane |
| [Ctrl]+b % | 水平分割兩個 pane |
| [Ctrl]+b [←/↓/↑/→] | 切換 pane |
| [Ctrl]+b x | 關閉當前的 pane |
| [Ctrl]+b c | 建立新的 window |
| [Ctrl]+b n | 移動到下個 window |
| [Ctrl]+b p | 移動到上個 window |
| [Ctrl]+b <index> | 移動到第<index>個 window |
| [Ctrl]+b & | 關閉當前的 window |
| [Ctrl]+b w | 打開操作面板,可以瀏覽所有 tmux session |
一開始認識 vim就要先了解其不同的模式:
其中最常用是一般模式 (Normal Mode)、插入模式 (Insert Mode)及命令列模式 (Command Line Mode)。一開始進入 vim時的模式為普通模式, 其他模式都要經過普通模式進入,透過 Esc鍵返回。
| 游標移動 | |
| h or [←] | 游標向左移動一個字元 |
| j or [↓] | 游標向下移動一個字元 |
| k or [↑] | 游標向上移動一個字元 |
| l or [→] | 游標向右移動一個字元 |
| 可以在指令前加上要執行指令的次數,例如 20l or 20[→],就可以往右移動 20個字元。 | |
| [Ctrl] + b or [PgUp] | 向上移動一頁 (backward) |
| [Ctrl] + f or [PgDn] | 向下移動一頁 (forward) |
| [Ctrl] + u | 向上移動半頁 (upward) |
| [Ctrl] + d | 向下移動半頁 (downward) |
| 0 or [Home] | 移動到此列的起始位置 |
| $ or [End] | 移動到此列最後面非空字元 |
| ^ | 移動到此列最前面非空字元 |
| + | 移動到下一列最前面的非空字元 |
| - | 移動到上一列最前面的非空字元 |
| gg | 移動到檔案的第一行 |
| G | 移動到檔案的最後一行 |
| {number}G 可以移動到第 {number}行,例如 20G,可以移動到檔案第 20行 | |
| H | 移動到目前顯示的第一行首字元 |
| M | 移動到目前顯示的中間一行首字元 |
| L | 移動到目前顯示的最後一行首字元 |
| [Space] | 向右移動一個字元 |
| [Enter] | 移動到下一行 |
| {number}[Space]可以向右移動 {number}個字元,與[→]不同的是,[Space]會移動到下一行。 {number}[Enter]可以向下移動 {number}行。 | |
| 搜尋與取代 | |
| /{string} | 向後搜尋 {string}字串 |
| ?{string} | 向前搜尋 {string}字串 |
| n | 執行上一個搜尋操作 |
| N | 反向執行上一個搜尋操作 |
| s/{string1}/{string2}/g | 將此行的 {string1}取代成 {string2} |
| %s/{string1}/{string2}/g | 將檔案裡的 {string1}取代成 {string2} |
| %s/{string1}/{string2}/gc | 將檔案裡的 {string1}取代成 {string2},取代前需要確認 |
| 編輯 | |
| x | 刪除游標後面的字元 |
| X | 刪除游標前面的字元 |
| dd | 刪除游標所在的這一行 |
| {number}X及 {number}x可以刪除游標前、後 {number}個字元。 {number}dd可以刪除游標往下 {number}行。 | |
| d1G | 刪除游標到第一行中的內容 |
| dG | 刪除游標到最後一行的內容 |
| d0 | 刪除游標前的這一行的內容 |
| d$ | 刪除游標後的這一行的內容 |
| yy | 複製游標所在的這一行 (yank) |
| {number}yy可以複製游標往下 {number}行。 | |
| y1G | 複製游標到第一行中的內容 |
| yG | 複製游標到最後一行的內容 |
| y0 | 複製游標前的這一行的內容 |
| y$ | 複製游標後的這一行的內容 |
| p | 在游標的後一行貼上 |
| P | 在游標的前一行貼上 |
| J | 將此行與下一行合成同一行 |
| u | 回到上一個操作的狀態 (undo) |
| [Ctrl] + r | 回到下一個操作的狀態 (redo) |
| . | 重複上一個操作 |
| 進入插入模式 | |
| i | 在游標字元處前插入 (insert) |
| I | 從此行第一個非空字元前插入 |
| a | 在游標字元處後插入 (append) |
| A | 從此行最後字元後插入 |
| o | 插入新的下面一行 (open) |
| O | 插入新的上面一行 |
| r | 進入取代模式,只取代一個字元 (replace) |
| R | 進入取代模式,直到離開 |
| Command Line Mode指令 | |
| :w | 儲存目前檔案變更 (write) |
| :q | 離開 vim (quit) |
| :w!可以強制寫入唯讀檔案。:q!可以強制不儲存離開。 | |
| :wq | 儲存並離開 |
| ZZ | 若檔案沒有修改,直接離開。若檔案有修改,儲存並離開 |
| ZQ | 不儲存離開 |
| :w {filename} | 將檔案另存到 {filename} |
| :r {filename} | 將另外一個檔案的內容加到游標位置的下一行 |
| :! {command} | 暫時離開 vim並執行 {command} |
| vim 可以同時打開多個檔案進行編輯。ex: vim a.txt b.txt。 | |
| :files | 列出目前 vim所開啟的檔案 |
| :n | 編輯下一個檔案 |
| :N | 編輯上一個檔案 |
| Visual Mode指令 | |
| v | 將游標經過的字元反白選擇 |
| V | 將游標經過的行反白選擇 |
| [Ctrl + v] | 以blcok的方式進行反白選擇 |
| y | 複製選擇的內容 |
| d | 刪除選擇的內容 |
| p | 貼上選擇的內容 |
參考連結:
鳥哥私房菜 第九章、vim程式編輯器
在閱讀關於 python multi-thread(多執行緒)、multi-process(多行程)及GIL的相關文章時,突然想到在公司寫的一個 script。
這 script需要使用同個 api發送不同參數的HTTP request,一開始的寫法是使用 for loop來執行,等到
request結束,再執行下一個。
由於每個 request需要幾十秒才會完成,所以整個 sciprt跑完就要花費好幾分鐘。如果能改寫成
使用 multi-thread的方式來發送 request,就能省下大量的時間。因為 GIL的關係,同時間只會
有一個 thread在執行,但以這 case來說已經很夠用了。
以下是要修改的 sample code,使用 for loop來執行 20次的 request:
使用 python threading來改寫:
建立一個 Thread物件,將要使用 threads來執行的 function傳入 target,並把 target所需要的引數以 tuple的形式傳入 args。
透過呼叫 start來啟動此 thread。
使用 join來等待此 thread結束。這裡使用 for loop來等待所有的 thread結束。 若沒有使用 join,thread可能會在主程式後才執行完成。
上面的程式碼雖然可以讓函式使用 thread的方式執行,卻沒辦法得到函式的返回值。其中一個解法是將函式改寫,使其將返回值存到 list中。
參考資料:
https://docs.python.org/zh-tw/3/library/threading.html
https://realpython.com/intro-to-python-threading/
官方網址:
https://github.com/ipmitool/ipmitool顯示 bmc相關資訊
顯示當前 bmc已啟用選項
啟用/停用 bmc選項
| option | desctiption |
|---|---|
| recv_msg_intr | Receive Message Queue Interrupt |
| event_msg_intr | Event Message Buffer Full Interrupt |
| event_msg | Event Message Buffer |
| system_event_log | System Event Logging |
| oem0 | OEM-Defined option #0 |
| oem1 | OEM-Defined option #1 |
| oem2 | OEM-Defined option #2 |
啟用 Event Message Buffer
ipmitool bmc setenables event_msg=on
停用 Event Message Buffer
ipmitool bmc setenables event_msg=off
顯示當前 sensor的資訊
透過 Sensor ID讀取特定 sensor的資訊
顯示當前 chassis狀態
顯示當前 chassis的電源狀態
開啟電源
關閉電源
重啟電源
關閉電源後開啟電源
更改開機裝置
| device | desctiption |
|---|---|
| none | Do not change boot device order |
| pxe | Force PXE boot |
| disk | Force boot from default Hard-drive |
| diag | Force boot from Diagnostic Partition |
| cdrom | Force boot from CD/DVD |
| bios | Force boot into BIOS Setup |
| floppy | Force boot from Floppy/primary removable media |
Clear CMOS
顯示 user在 channel的相關資訊
顯示 channel 1的 user資訊
ipmitool user list 1
設定 user的名稱
設定 user id 2的名稱為 testuser
ipmitool user set name 2 testuser
設定 user的密碼
設定 user id 2的密碼為 test
ipmitool user set password 2 test
啟用 BMC存取
啟用 user id 2的 BMC存取
ipmitool user enable 2
停用 BMC存取
顯示 channel的資訊
顯示 channel 1的資訊
ipmitool channel info 1
設定 user存取 channel
設定 user id 2在 channel 1的 ipmi on及privilege level為 4
ipmitool channel setaccess 1 2 ipmi=on privilege=4
最近在讀早期 linux kernel的相關書籍,其在塊設備章節提到 hard disk controller(硬碟控制器)有很多機械硬碟物理層面的相關名詞。
因為這時的 hd controller的操作使用底層的細節,用於操作硬碟控制器的命令參數。
示意圖中是以 3個磁盤(Platters)及 6個磁頭 (Heads)所組成的硬碟,磁盤的兩面都能讀寫。硬碟主要以兩組馬達控制,一組控制磁盤的旋轉,另一組控制磁頭的移動。
Sector (磁區,扇區)
磁區是磁盤上以相同的角度劃出的等分區域,也是硬碟最小的讀寫單位,最開始統一的單位為 512 Bytes。
Track (磁軌,磁道)
磁軌是磁頭在磁盤上以相同半徑所畫出的軌跡。
Cylinder (磁柱,柱面)
磁柱是所有磁盤上相同半徑的磁道所形成的圓柱體。
早期的硬碟定址使用 Cylinder-Head-Sector方法,從上方的硬碟物理構造可以看出,以這三個參數就能定位到某個確定的磁區。這方法在之後被 LBA(Logic Block Address)所取代。
官方網址:
https://com0com.sourceforge.net/
com0com可以在 Windows下虛擬出一組對接com port。
安裝完後,可用putty打開兩個com port進行測試是否可互傳訊息。
UEFI console 主要由兩個 protocol組成:
EFI System Table 幾個與 console相關的項目:
Console input device的 handle,此 handle必須 support Simple Text Input Protocol 及 Simple Text Input Ex Protocol,ConIn 則為指向此 Simple Text Input Protocol 的指標。
Console output device的 handle,此 handle必須 support Simple Text Output Protocol ,ConOut 則為指向此 Simple Text Output Protocol的指標。
Standard error console device的 handle,此 handle必須 support Simple Text Output Protocol ,StdErr則為指向此 Simple Text Output Protocol的指標。
與 console相關的 UEFI global variable:
預設 console input device的 device path
所有可能的 console input device的 device path
預設 console output device的 device path
所有可能的 console output device的 device path
預設 error console的 device path
所有可能的 error console的 device path
Reset input device硬體
讀取按鍵輸入
等待按鍵輸入
比起 ReadKeyStroke能讀取更多種按鍵輸入
讓使用者可以註冊或取消註冊組合按鍵所觸發的 notification function
設定 input device的狀態。EX:Caps Lock actice
將 Unicode字串輸出到 output device
設定 OutputString()及 ClearScreen()的前景和背景的顏色
清除 output device 的output
設定游標的位置
透過 Console driver來產生多一層 Text I/O Interface以達到 remote 介面與 UEFI間的
溝通
Console Splitter來同時支援多個 input及 output console device,透過 hook EFI System
Table的 ConIn/ConOut/StdErr來達成,且ConIn等 UEFI global可以包含多個 active console
的 device path
UEFI也提供與網路溝通的能力,主要包含的元件有:
這功能由 UNDI(Universal Network Driver Interface)提供,並負責產生 Simple
Network Protocol
提供封包層級的網卡操作介面
在公司的工作機是使用 Windows筆電,有時候會需要連到遠端 Linux機器,記錄一些會使用
到的指令。
根據微軟官網,Windows 本身已經內建 SSH client應用程式。
透過 ssh連線到遠端的主機,之後會跳出提示輸入密碼。
退出 ssh連線回到 Windows Terminal。
SCP是使用 SSH的遠端加密傳輸檔案指令。
將本地的 C:\a.txt傳送到遠端 machine的 user目錄中。
將本地的 C:\a.txt傳送到遠端 machine的 user目錄中,並命名成 b.txt。
將遠端 machine的 user目錄中 b.txt傳送到本地端的 C:\目錄中。
將遠端 machine的 user目錄中 b.txt傳送到本地端的 C:\目錄中,並命名成 c.txt。
將遠端 machine的 user目錄中 test目錄遞迴複製傳送到本地端的 C:\ (C:\test)。
將本地端的 C:\test目錄遞迴複製到遠端的 user目錄中 (~/test)。
最近開始在上 Coursera台大林軒田的 Machine Learning的課程,第二周的內容重點是關於 PLA
(Perceptron Learning Algorithm),於是就想實作關於 PLA的程式碼。
首先是要有一組線性可分的資料,但要手動產生線性可分資料過於麻煩,而 scikit-learn提供
datasets 這個為機器學習使用者所用的資料集合。
以 iris plant dataset為例,其提供了鳶尾花的植物特徵資料:
三個品種的鳶尾花各50組,總共150組資料。透過 load_iris來獲得:
https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_iris.html
參考scikit-learn提供的範例The Iris Dataset來看其資料分布的情形。可以用來練習線性可分
的情況,也能練習在線性不可分下中使用 Pocket Algorithm。
用 matplotlib畫出其資料分布圖:
上篇文章:
[Python] Decorator 裝飾器
在使用 decorator時,會使得原本被包裹的 function 的 attribute資料遺失。
Output:
可使用 functools的 decorator wraps來避免這種情況:
Output:
wraps提供了另一個有用的功能,可以使已經套用過 decorator的 function回復成套用前的
function。透過 __wrapped__這個屬性來使用原本的 function。
Output:
最近發現自己在 Python上的技巧需要提升,雖然以前就知道 Decorator的概念,但我在
實際應用上很少使用,趁此機會來重新理解下。
Decorator簡單來說,是一種 function,並以另一個 function作為輸入,用來擴充輸入
function的功能。
以下面程式碼為例:
Output:
這裡 hello_alice使用 say_hello當作參數傳入,
hello_alice就是作為 say_hello的
decorator。
通常 decorator會使用更簡潔的語法糖 "@"包裝,使用上面的範例修改:
Output:
@hello_alice代表將 say_hello當作參數傳入 hello_alice function。
Python的 function也能夠在另一個 function中被定義,稱為 inner function。inner function可以
讓 decorator的使用更加靈活:
Output:
其中 wrapper就是作為 decorator @greet的 inner function。 並且會使用 *args與 **kwargs來接收參數。
一個 decorator經典的範例是用於測量 function執行所花的時間:
使用 decorator @measure的來測量 count_down function所花費的時間。