Python 中的前向宣告

Aditya Raj 2023年1月30日 2022年5月17日
  1. 前向宣告
  2. 為什麼我們需要 Python 中的前向宣告
  3. Python 中變數的前向宣告
  4. 在 Python 中前向宣告一個函式
  5. まとめ
Python 中的前向宣告

本文將討論我們是否可以在 Python 中實現前向宣告。我們還將研究在 Python 中模擬前向宣告的不同方法。

前向宣告

前向宣告是在實現函式、類或變數用法之前宣告函式、類或變數的簽名。

在 C++ 中,前向宣告用於定義函式的簽名,如下所示。

#include <iostream>

using namespace std;

int myFun(int,int);

int main()
{
    cout<<myFun(5,10);

    return 0;
}

int myFun(int a, int b){
    int s= a+b;
    return s;
}

在上面的示例中,我們使用前向宣告來使用語句 int myFun(int,int); 定義函式 myFun 簽名。在此宣告之後,編譯器知道原始碼檔案中存在一個名為 myFun 的函式。

因此,即使該函式在其定義之前被呼叫,程式也不會出現任何錯誤並且會成功執行。

在 Python 中,我們不使用前向宣告。但是,在編寫 Python 程式的原始碼時,使用前向宣告可以帶來各種好處。

為什麼我們需要 Python 中的前向宣告

雖然 Python 沒有前向宣告的語法規範,但在很多情況下我們需要前向宣告。

如果函式 Fun1 在實現 Fun2 之前使用 Fun2,則檢視程式碼的人可能不知道 Fun2 的簽名、輸入或輸出。我們可以通過使用前向宣告來通知程式碼審查者關於 Fun2 的簽名來避免這種情況。

  • 有時,我們可能會將使用者定義類的物件傳遞給函式。同樣,如果類沒有在函式之前實現,我們將需要顯式地顯示類的屬性。

    如果我們在 Python 中使用前向宣告,就可以避免這種情況。

  • 與作為引數傳遞類似,如果使用者定義的類是另一個類的屬性,那麼瞭解給定的類物件的行為對於理解程式碼至關重要。通過 Python 中的前向宣告,我們可以告知類物件的行為。

  • 有時,我們可能需要告知程式碼審查者變數的資料型別。在這種情況下,我們可以使用前向宣告來定義變數的屬性。

Python 中變數的前向宣告

我們可以使用前向宣告來使用型別提示和型別模組來宣告變數。讓我們一一討論它們。

在 Python 中使用型別提示進行前向宣告

型別提示允許我們定義變數的型別。

語法:

var: type

這裡,

  • var 是變數名。
  • type 是變數的資料型別。

你可以使用型別提示來轉發宣告 Python,如下所示。

myStr: str
myNumber: int

在上面的例子中,變數 myStrmyNumber 在宣告之前是不存在的。因此,在使用型別提示的前向宣告之後使用 myStrmyNumber 將導致 NameError 異常,如下所示。

myStr: str
myNumber: int
print(myStr)
print(myNumber)

輸出:

Traceback (most recent call last):
  File "/home/aditya1117/pythonProject/string12.py", line 3, in <module>
    print(myStr)
NameError: name 'myStr' is not defined

在這裡,變數 myStrmyNumber 存在。然而,它們還沒有被分配一個值。

因此,它們既沒有分配記憶體,也沒有出現在程式的符號表中。因此,當我們使用變數而不給它們賦值時,就會發生 NameError 異常。

要使用該變數,你必須首先為其分配一個值。

myStr: str
myNumber: int
myStr = "Delft-stack"
myNumber = 123
print(myStr)
print(myNumber)

輸出:

Delft-stack
123

一旦我們為變數賦值,它們就會被分配記憶體並被新增到符號表中。因此,程式不會出錯併成功執行。

在這裡,你可以說使用型別提示的變數前向宣告與註釋一樣好。

在 Python 中使用型別模組的前向宣告

使用型別提示定義使用者定義類的物件需要在變數宣告之前實現。否則,程式將遇到 NameError 異常。

你可以在以下示例中觀察到這一點。

myStr: str
myNumber: int
myObject: myClass

輸出:

Traceback (most recent call last):
  File "/home/aditya1117/pythonProject/string12.py", line 3, in <module>
    myObject: myClass
NameError: name 'myClass' is not defined

這裡沒有定義字面量 myClass。因此,程式會遇到 NameError 異常。

為了避免這樣的錯誤,我們首先需要定義 myClass 是一個類名。我們可以使用 typing 模組中定義的 NewType() 函式。

NewType() 函式將表示類名的字串作為其第一個輸入引數。它將新類的父類作為第二個引數。

執行後,它返回一個新函式,我們可以將其分配給新類的類名。之後,我們可以像在型別提示中使用 int、float 和 double 這樣的文字一樣使用新的類名。

為了定義一個 myClass 型別的類,我們將傳遞字面量 myClass 作為第一個輸入引數,並將 None 物件作為第二個引數。執行完 NewType() 函式後,我們可以在型別提示中使用 myClass 進行前向宣告,如下所示。

import typing

myClass = typing.NewType("myClass", None)
myStr: str
myNumber: int
myObject: myClass

程式不會遇到 NameError 異常,因為我們已經宣告 myClass 是一個物件型別。

在 Python 中前向宣告一個函式

在 Python 中,你應該始終在使用它之前定義一個函式。你可以在另一個函式 fun2 的定義中使用函式 fun1

但是,你需要確保在定義 fun1 之前不會呼叫 fun2。否則,程式將遇到 NameError 異常。

fun1()

def fun1():
    print("I am in fun1")

輸出:

Traceback (most recent call last):
  File "/home/aditya1117/string12.py", line 1, in <module>
    fun1()
NameError: name 'fun1' is not defined

Process finished with exit code 1

在這裡,我們在定義之前的 main() 函式中使用了函式 fun1()。由於這個原因,程式遇到了一個 NameError 異常,表明名稱 fun1 沒有定義。

僅在定義後使用 fun1 可以避免 NameError 異常,如下所示。

def fun1():
    print("I am in fun1")

fun1()

輸出:

I am in fun1

まとめ

本文討論瞭如何在 Python 中模擬前向宣告。前向宣告僅在使用型別提示來宣告使用者定義型別的變數時才有意義。

此外,僅在對變數強制執行資料型別時才需要型別提示。因此,僅在對變數實施型別約束時才使用前向宣告。

否則,你的程式將無緣無故地做額外的工作。最好總是在 Python 中使用它之前定義一個函式。