Pyslvs 使用手冊

  • Home
    • Site Map
    • reveal
    • blog
  • 簡介
    • 機構與機器
    • Pyslvs 介面
      • Mechanism
      • Inputs
      • Synthesis
  • 操作
    • 模擬操作
      • 曲柄滑塊
      • 四連桿
    • 尺寸合成操作
    • 構造合成操作
    • 由現有設計進行尺寸合成
  • 下載
  • 分析
    • 三角形表示式
  • 範例
    • 模擬範例
      • Quick return mechanism
      • Watt six-bar linkage
      • Stephenson six-bar linkage
      • Klann linkage
    • 尺寸合成範例
    • 結構合成範例
    • 產品設計範例
  • Python 教學
    • 控制流程
    • 簽章
    • 複製與參照
    • 物件導向
    • 類型註解
  • 開發
    • Windows 開發
      • 環境修正
      • PyInstaller 對 Windows 的支援
    • Ubuntu 開發
      • AppImage 包裝
    • Mac OS X 開發
      • PyInstaller 對 Mac OS X 的支援
    • 參與協同
      • 註解規則
      • 命名規則
      • 類型註解規則
    • Kmol-editor
  • 參考
    • Misc
控制流程 << Previous Next >> 複製與參照

簽章

簽章

函式 (Function) 能在特定需求時輸入資料與輸出結果,輸入與輸出值稱為參數 (Argument)。

以強型別程式語言 C 來說,一個輸入 3 個參數,輸出 1 個參數的函式是這樣宣告的:

int func(int p0, int p1, float p2);

但是 Python 沒有類型標示,因此函式會如此定義:

def func(p0, p1, p2):
    ...

函式 func 的輸入與輸出類型(如「輸入 3 個參數、輸出 1 個參數」),稱為簽章 (Signature)。

Python 是弱型別語言,簽章只有強制規定參數數量,而沒有規定參數類型。

另外,單一化的輸入需求不足以滿足函式應用範圍,而產生多載 (Overload) 的功能,以支援不同選項、不同類型的輸入。以強型別程式語言 C++ 為例:

// 注意:C 語言不支援多載。
// C++ 多載宣告,編譯時會依照簽章自動生成四種函式。
// 預設值也算是一種多載。
// 撰寫程式時只需要寫 func 即可。
int func(int p0, int p1, long double p2, bool p3 = false);
int func(int p0, int p1, double p2) {
    // 會需要寫轉換型別的接繞函式。
    // 如果簽章搞錯,會造成無限遞迴 (Recursive)。
    return func(p0, p1, (long double) p2);
}
int func(int p0, int p1, float p2) {
    // 會需要調整設定。
    return func(p0, p1, (long double) p2, true);
}

上面的例子中,為了支援強型別的標記,函式必須製作多種不同類型的簽章,若有更多需求,則必須使用模板 (Template):

// 模板宣告,編譯時會自動生成多載簽章。
template <typename T>
int func(int p0, int p1, T p2);
// 如果要支援其他參數,又要混合多載。
int func(int p0, int p1, long double p2, bool p3 = false);

在 Python 中,沒有多載、沒有模板、沒有型別要求,因此大幅簡化定義。唯一要解決的問題是滿足參數數量的變化。

預設值

預設值只能從最後開始使用等於 = 符號連續定義,不可以隨意指定其中的參數。

在呼叫時使用 = 符號為關鍵字參數,與定義時相同,只能從最後開始連續填入。

def func(p0, p1, p2=20, p3=True):
    ...

# 可以這樣使用:
func(a0, a1, a2, a3)  # 全部填滿。
func(a0, a1, a2)  # 使用部分預設值。
func(a0, a1, p3=a3)  # 名稱對應,使用部分預設值。
func(a0, a1)  # 全部使用預設值。

強制名稱對應

使用特殊符號 *,其後所有參數不分順序,強制使用名稱對應。如果有參數沒有填入或沒有預設值,會引發錯誤。

def func(p0, p1, *, p2, p3=True):
    ...

# 可以這樣使用:
func(a0, a1, p2=a2, p3=a3)  # 全部填滿。
func(a0, a1, p2=a2)  # 名稱對應,全部使用預設值。

順序收集與對應收集

使用星號 *,該變數會收集多餘填入的位置參數 (Positional argument)。多餘的參數會收集成 tuple 容器,若沒有多餘參數,該參數會是空的 tuple 容器。

使用雙星號 **,該變數會收集多餘填入的關鍵字參數 (Keyword argument)。多餘的參數會收集成 dict 容器,若沒有多餘參數,該參數會是空的 dict 容器。

兩者可以擇一或混合使用,但是定義時單星號參數一定要在前面,其後所有參數不分順序。

def func(p0, p1, *p2, **p3, p4, p5=True):
    ...

# 可以這樣使用:
func(a0, a1, p4=a4, p5=a5)  # 全部填滿。
# p2 = ()
# p3 = {}
func(a0, a1, p4=a4)  # 全部使用預設值。
# p2 = ()
# p3 = {}
func(a0, a1, b1, b2, r=b3, s=b4, p4=a3)  # 多餘值。
# p2 = (b1, b2)
# p3 = {'r': b3, 's': b4}

針對「順序容器(如 tuple、list)」或「成對容器(如 dict)」,填入時可以用 *、** 按關係填入。不過不符合簽章仍然會引發錯誤,應當注意。如:

func(*[a0, a1, b1, b2], **{'r':b3, 's': b4, 'p4': a3})
# 或用變數:
a_list = [a1, b1, b2]
b_dict = {'r':b3, 'p4': a3}
func(a0, s=b4, *a_list, **b_dict)

控制流程 << Previous Next >> 複製與參照

Copyright © All rights reserved | This template is made with by Colorlib