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
在上面的例子中,变量 myStr
和 myNumber
在声明之前是不存在的。因此,在使用类型提示的前向声明之后使用 myStr
或 myNumber
将导致 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
在这里,变量 myStr
和 myNumber
存在。然而,它们还没有被分配一个值。
因此,它们既没有分配内存,也没有出现在程序的符号表中。因此,当我们使用变量而不给它们赋值时,就会发生 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 中使用它之前定义一个函数。