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 中使用它之前定义一个函数。