Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个python函数代码是如何工作的?_Python_Function_Matplotlib - Fatal编程技术网

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

这个python函数代码是如何工作的?,python,function,matplotlib,Python,Function,Matplotlib,这来自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

这来自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
是返回函数的参数。

这是一个Python装饰器——基本上是一个函数包装器。(阅读PEP 318中关于装饰师的所有内容--)

如果您仔细查看代码,您可能会发现如下内容:

def some_func(name, val):
    # ...
some_func = with_default_value(some_func, 'the_default_value')
如果缺少name或val参数(如果它们被设置为None,则可能是无),则此装饰器的意图似乎是提供一个默认值。

关于它工作的原因:

with_default_值返回一个函数对象,它基本上是嵌套newfunc的一个副本,“func”调用和默认值用传递给with_default_值的任何内容替换

如果有人使用“foo=with_default_value(bar,3)”,则返回值基本上将是一个新函数:

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

因此,您可以获取该返回值,并调用它

这个带有默认值的
函数通常被称为(不精确地)闭包(从技术上讲,闭包是返回的内部函数,这里是
newfunc
——参见示例)。更一般地说,带有默认值的
是一个高阶函数(“HOF”):它将函数(
func
)作为参数,还返回一个函数(
newfunc
)作为结果

我看到一些答案将其与Python中的装饰器概念和构造相混淆,这肯定是而不是的情况——特别是因为您提到
func
通常是一个内置函数,例如
int
。decorator也是高阶函数,但非常特殊:返回其函数参数的修饰版本,即“丰富”版本的函数参数(必须是唯一的参数--“带参数的Decorators”是通过多层次的函数/闭包嵌套获得的,而不是通过给decorator提供多个参数),它被重新分配给与该函数参数完全相同的名称(因此通常具有相同的签名——否则使用decorator将是非常奇怪的、非惯用的、不可读的等等)

因此,忘记装饰器吧,它与案例完全无关,而关注
newfunc
闭包。词汇嵌套函数可以引用(但不能重新绑定)封闭函数的所有局部变量名(包括参数名,因为参数是局部变量)——这就是它被称为闭包的原因:它“封闭”在这些“自由变量”之上。在这里,
newfunc
可以引用
func
default
——并且确实如此

在Python中,高阶函数是非常自然的事情,特别是因为函数是一级对象(因此,无需做任何特殊的操作即可将其作为参数传递、作为函数值返回,甚至将其存储在列表或其他容器中等),函数和其他类型的对象之间没有名称空间上的区别,也没有仅仅因为提到了函数就自动调用函数,等等(在其他语言中,这一点比较难——有点难,或者更难,这取决于其他语言)。在Python中,提到一个函数就是——提到;只有当函数对象(以名称或其他方式引用)后面有括号时,才会发生调用

这就是这个例子的全部内容——如果您对其他一些具体方面还有疑问,请随意编辑您的问题,在这里发表评论,等等

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

for i in range(len(buttons)):
  buttons[i].onclick(lambda: mainwin.settitle("button %d click!" % i))
但这并不正确--
lambda
中的
i
是延迟绑定的,因此在单击一个按钮时,
i
的值总是最后一个按钮的索引,无论单击了哪个按钮。有各种可行的解决方案,但封闭工厂是一种极好的可能性:

def makeOnclick(message):
  return lambda: mainwin.settitle(message)

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

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

是否应该有一个类似“if ismissing”的空格?确切地说,除了新代码通常看起来更像:@with_default_value(some_func,'the_default_value')def some_func(name,val):#……我认为如果使用@语法(在函数定义之前),您必须有一个装饰器工厂(而这是一个纯除臭剂——2级深)。装饰器工厂可以接受参数,但不需要。除非在3中发生了更改。x@dcrosta我不这么认为。我一直在使用语法和装饰器互换,没有什么坏处。我猜我的立场是正确的。谢谢你的区分。这个HOF怎么会被调用呢?习语——就像大多数HOFs返回闭包一样,我只是认为它是实现函数工厂的一种简便方法。回答很好,那是一场战斗,首先我认为是另一个人完成的,然后你来接地!谢谢,我想我们都学到了一些东西!我想知道你是否还有其他类似的例子?只是好奇而已。不,w如果很难找到一个/做一个,那就很遗憾。