在functools.partial示例定义中,函数属性用在返回的partial函数对象中:
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
如果这些属性被移除,会有什么潜在的问题呢?如果newfunc还活着,Python不应该保留对func、args和keywords的引用吗?
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
return newfunc
我知道functools.partial的实际实现可能完全不同,但是如果它是这样实现的,为什么属性是必需的呢?
3条答案
按热度按时间x33g5p2x1#
任何实现都需要将函数及其固定参数存储在某个地方。在您的两个示例中,我们使用了闭包。当这些
partial
实现返回时,这些值将被添加到返回的闭包中。在这种情况下,.func
、.args
和.keywords
是冗余的。闭包已经有了它们。因此,使用选项2。但是python为这项工作创建了一个类,
.func
,.args
和.keywords
是所需数据的唯一副本,类的实现允许你以一种有效的方式(它结合了两个partial的参数)创建partial的partial,并且在构建对象的字符串显示时更整洁。但是你的第二个关闭机制是好的,只是做事情的方式不同。
hec6srdp2#
由于
partial
实际上是一个类型,因此提供一个等效的 class 比将其转换为函数更有意义。注意,所有被赋值给函数属性的东西现在都被赋值给
self
的示例属性。当你调用partial
的示例时,你调用的是原始函数,保存的参数与“immediate”参数合并。至于为什么文档使用函数,也许人们认为嵌套函数比解释
__call__
的作用要简单?这个函数使用函数属性而不是闭包,正是因为
partial
的实际实现也将保存的参数存储在名为args
和keywords
的属性中,毕竟它们试图模拟真实的类型。gopyfrb33#
显然,函数属性在分部函数的实现中实际上并不是必需的,只是因为API需要才添加它们,这里有两组变量:一个是在newfunc的闭包中,另一个是以属性的形式,newfunc不使用这些属性。
感谢@juanpa.arrivillaga的澄清。