为什么Python允许使用错误数量的参数调用函数?

2024-06-01 13:24:41 发布

您现在位置:Python中文网/ 问答频道 /正文

Python是我的第一种动态语言。我最近编写了一个函数调用,错误地提供了错误数量的参数。此操作失败,在调用该函数时出现异常。我希望即使在动态语言中,在解析源文件时也能检测到这种错误。在

我知道实际参数的类型在调用函数之前是未知的,因为同一个变量在不同的时间可能包含任何类型的值。但是只要解析源文件,参数的数目就知道了。它不会在程序运行时更改。在

所以这不是一个哲学问题

为了将这个问题保持在堆栈溢出的范围内,让我用这样的措辞来回答这个问题。Python是否提供了一些特性,要求它延迟检查函数调用中的参数数量,直到代码实际执行为止?在


Tags: 函数程序运行语言类型参数数量堆栈错误
2条回答

传递的参数数量是已知的,但实际调用的函数不知道。请参见以下示例:

def foo():
    print("I take no arguments.")

def bar():
    print("I call foo")
    foo()

这可能看起来很明显,但是让我们把它们放入一个名为富巴尔.py". 现在,在交互式Python会话中,执行以下操作:

^{pr2}$

这是显而易见的。现在是有趣的部分。我们将定义一个需要非零数量参数的函数:

>>> def notfoo(a):
...    print("I take arguments!")
...

现在我们做一些叫做monkey patching的事情。实际上,我们可以在fubar模块中替换函数foo

>>> fubar.foo = notfoo

现在,当我们调用bar时,将引发一个TypeError;名称foo现在指的是我们上面定义的函数,而不是原来的函数-foo。在

>>> fubar.bar()
I call foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/horazont/tmp/fubar.py", line 6, in bar
    foo()
TypeError: notfoo() missing 1 required positional argument: 'a'

因此,即使在这样的情况下,很明显被调用的函数foo不带参数,Python也只能知道它实际上是在执行源代码行时被调用的foo函数。在

这是Python的一个特性,它使它强大,但也会导致它的一些缓慢。事实上,making modules read-only to improve performance has been discussed在python ideas mailinglist上,但它并没有得到任何真正的支持。在

Python无法预先知道您将调用哪个对象,因为作为动态的,您可以将函数object交换出去。任何时候。每个对象都可以有不同数量的参数。在

这里有一个极端的例子:

import random

def foo(): pass
def bar(arg1): pass
def baz(arg1, arg2): pass

the_function = random.choice([foo, bar, baz])
print(the_function())

上面的代码有2/3的机会引发异常。但是Python无法预知是否会发生这种情况!在

我甚至还没有开始介绍动态模块导入、动态函数生成、其他可调用对象(任何具有__call__方法的对象都可以被调用)或捕获所有参数(*args**kwargs)。在

但为了更清楚地说明这一点,你在问题中陈述:

It is not going to change while the program is running.

在Python中,情况并非如此,一旦加载模块,就可以删除、添加或替换模块命名空间中的任何对象,包括函数对象。在

相关问题 更多 >