这个python函数代码是如何工作的?

2024-10-01 04:59:21 发布

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

这是来自matplotlib中csv2rec的源代码

如果这个函数的参数只有“func,default”,它怎么工作?在

def with_default_value(func, default):
    def newfunc(name, val):
        if ismissing(name, val):
            return default
        else:
            return func(val)
    return newfunc

ismissing接受一个名称和一个值,并确定是否应该在numpy数组中屏蔽该行。在

func可以是str、int、float或dateparser…它转换数据。也许不重要。我只是想知道它怎么能得到“name”和“value”

我是初学者。谢谢你给我20美分!我希望能变得足够好去帮助别人!在


Tags: 函数namedefault参数return源代码matplotlibvalue
3条回答

至于它为什么起作用:

with_default_value返回一个函数对象,它基本上是嵌套newfunc的副本,其中“func”调用和默认值将以传递给“default”_value的任何内容作为子项。在

如果有人做了'foo=with_default_value(bar,3)',返回值基本上将是一个新函数:

def foo(name, val):
    ifismissing(name, val):
        return 3
    else:
        return bar(val)

所以你可以取这个返回值,然后调用它。在

这是一个Python装饰器——基本上是一个函数包装器。(阅读pep318--http://www.python.org/dev/peps/pep-0318/中有关装饰器的所有内容)

如果你仔细查看代码,你可能会发现如下所示:

def some_func(name, val):
    # ...
some_func = with_default_value(some_func, 'the_default_value')

如果缺少name或val参数(假设它们被设置为None),那么这个decorator的意图似乎是提供一个默认值。在

这个with_default_value函数通常被称为“闭包”(从技术上讲,闭包是返回的内部函数,这里newfunc——参见示例here)。更一般地说,with_default_value是一个高阶函数(“HOF”):它以函数(func)为参数,并返回一个函数(newfunc)作为结果。在

我已经看到一些答案将这与Python中的decorator概念和构造混淆在一起,这绝对是而不是这种情况——特别是因为您经常提到func是一个内置的,比如int。decorator也是高阶函数,但更具体:它返回一个修饰的,即“enriched”版本的函数参数(必须是唯一的参数--“Decorators with arguments”是通过一个更高级别的函数/闭包嵌套获得的,不是通过给decorator HOF一个以上的参数),它被重新分配到与函数参数完全相同的名称(因此通常具有相同的签名——否则使用decorator将是非常特殊的、非惯用的、不可读的,等等)。在

因此,忘掉与case完全无关的decorators,而只关注newfunc闭包。一个词汇嵌套的函数可以引用(尽管不是重新绑定)封闭函数的所有局部变量名(包括参数名,因为参数是局部变量)——这就是它被称为闭包的原因:它对这些“自由变量”是“闭合的”。在这里,newfunc可以引用func和{}——而且确实如此。在

在Python中,高阶函数是非常自然的事情,尤其是因为函数是一类对象(因此,没有什么特别的事情需要做,可以将它们作为参数传递,作为函数值返回,甚至可以将它们存储在列表或其他容器中,等等),而且函数和其他类型的对象之间没有名称空间的区别,也没有仅仅因为提到了函数就自动调用函数等等(这更难——有点难,或者更难,这取决于在其他语言中,确实有很多这样的区别)。在Python中,提到一个函数就是——提到;只有当函数对象(通过名称或其他方式引用)后跟括号时才会发生调用。在

这就是这个例子的全部内容——如果您对其他方面仍有疑问,请随时编辑您的问题、评论等!在

编辑:因此OP礼貌地评论,要求提供更多“关闭工厂”的例子。这里有一个——想象一下某种抽象的图形用户界面工具包,您正在尝试:

for i in range(len(buttons)):
  buttons[i].onclick(lambda: mainwin.settitle("button %d click!" % i))

但这并不正确-i中的i是延迟绑定的,所以当一个按钮被点击时,^{的值总是会是最后一个按钮的索引,不管单击了哪个按钮。有各种可行的解决方案,但关闭工厂是一种很好的可能性:

^{pr2}$

这里,我们使用闭包工厂来调整变量的绑定时间!-)以某种特定的形式,这是关闭工厂的一个非常常见的用例。在

相关问题 更多 >