什么是 python 中的 _curried 方法,它们是如何生成的?

Posted

技术标签:

【中文标题】什么是 python 中的 _curried 方法,它们是如何生成的?【英文标题】:What is a _curried method in python and how are they generated? 【发布时间】:2015-04-05 20:01:26 【问题描述】:

如果这是一个骗局,请提前道歉;我搜索“_curried python”得到了 14 个结果,然后简单地 _curried”,结果只增加了 33 个,似乎没有任何帮助......

问题:我今天在我们的代码库中发现了我最初认为是一个错字,这里是嫌疑人:

student.recalculate_gpa()

现在,我怀疑这是一个错字,因为student 是一个没有recalculate_gpa 方法的Student 类的实例。但是,它确实有一个calculate_gpa 方法:

class Student(User):
    ...
    def calculate_gpa(self):
        # some calculations...

User 是标准的 django 用户类。)但是,代码没有出错,这对我来说毫无意义。所以我做了一个检查,发现了这个:

... (a bunch of methods)
('calculate_gpa', <unbound method Student.calculate_gpa>),
... (some more methods)
('recalculate_gpa', <unbound method Student._curried>),

奇怪,recalculate_gpa 其实是一种方法。但它到底是从哪里来的呢?我在我们的代码库中搜索了“_curried”,但什么也没找到,所以这一定是一些与 Django 相关的行为。当然,我希望在我们项目的某个地方,我们已经描述了动态命名函数是如何形成的,因为 recalculate 似乎是 calculate 的合理派生,但老实说,我不知道从哪里开始。

因此,我的问题是:像上面那样的柯里化方法是如何生成的,我应该从哪里开始寻找我们自己的代码库是如何柯里化的?

提前致谢!

【问题讨论】:

你继承的User是什么? 抱歉,这是标准的 django 用户类 有类装饰器之类的吗? 学生周围没有装饰器 这是 Django 相关的,而不是“内置 Python 行为” - github.com/django/django/blob/master/django/utils/… 【参考方案1】:

柯里化方法是在实际调用之前部分调用方法

例如

from functools import partial
from itertools import count
def my_pow(x,y):
    return x**y

curried_pow2n = partial(my_pow,x=2)

for i in count(0): #print the 2**i
    print curried_pow2n(i)

您也可以使用 lambda 轻松实现它

curried_pow2n = lambda x:return my_pow(2,x)

虽然我不确定这与您的实际问题有什么关系 ...

django 还提供了一个与 functools.partial 非常相似的 curry 方法

from django.utils.functional import curry    

lols = 'lols':'lols'
formset = modelformset_factory(MyModel, form=myForm, extra=0)
formset.form = staticmethod(curry(MyForm, lols=lols))

(来自https://***.com/a/25915489/541038)

所以你可能想寻找Student.recalculate_gpa =

或者也许在self.recalculate_gpa =Student.__init__方法中

你可能不会发现它在寻找def recalculate_gpa

【讨论】:

这是疯狂的事情,当我在整个项目中使用 grep 搜索“recalculate_gpa”时,恰好有一个成功:方法调用student.recalculate_gpa() 如果你 grep curry 怎么办(创建它可能有一些技巧)(你确定你也 grep 了整个项目吗?) 尝试:[cell.cell_contents for cell in Student.recalculate_gpa.__closure__] 看看封装了哪些函数以及使用了哪些参数。 我确定这不是魔法:P ...@QuentinDonnellan ...如果过于针对您的特定问题,请谨慎发布您自己的答案,其他人可能不会觉得它有帮助 谢谢,这很有帮助!面对ImportError: cannot import name 'curry' from 'django.utils.functional'这个错误的每个人,你可以用“functools”中的“partial”替换curry方法。只需导入此答案中提到的部分方法,并在使用它的地方将 curry 替换为 partial() 即可。由于 django 已经在最新版本中删除了这个包。部分工作方式完全相同!

以上是关于什么是 python 中的 _curried 方法,它们是如何生成的?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Curry-Howard 对应来证明下一个命题逻辑陈述的正确方法是啥?

python 库整理:toolz.curried (整理中)

SML中来自元组的“Curry”

JS中的柯里化(currying)

python中的内方法

[Ramda] Basic Curry with Ramda