Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.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_Python 2.7_Closures - Fatal编程技术网

Python 创建修复了一些变量的函数副本

Python 创建修复了一些变量的函数副本,python,python-2.7,closures,Python,Python 2.7,Closures,假设我有一个函数 def multiply_by(x, multiplier): return x * multiplier 如何创建该函数的副本并修复该函数中的乘数 multiply_by_5 = multiply_by? <-- here I need python magic Python2.7中有什么方法可以做到这一点吗?您可以与关键字参数一起使用: >>> def multiply_by(x, multiplier): ... retu

假设我有一个函数

def multiply_by(x, multiplier):
    return x * multiplier
如何创建该函数的副本并修复该函数中的乘数

multiply_by_5 = multiply_by?    <-- here I need python magic
Python2.7中有什么方法可以做到这一点吗?

您可以与关键字参数一起使用:

>>> def multiply_by(x, multiplier):
...     return x * multiplier
...
>>> from functools import partial
>>> multiply_by_5 = partial(multiply_by, multiplier=5)
>>> multiply_by_5(2)
10
正是为了这个

你可以像这样使用它

import functools
multiply_by_5=functools.partial(multiply_by,multiplier=5)

如果您无法更改
multiply\u by()
函数,最简单也是最好的方法可能是

def multiply_by_5(x):
    return multiply_by(x, 5)
如果您真的想要一行程序,也可以使用
lambda

但是,您可能希望将第一个函数更改为

def multiply_by(x, multiplier = 5):
    return x * multiplier
然后您可以执行以下任一操作:

print(multiply_by(4, 3))
12

print(multiply_by(2))
10
正如@niemmi所建议的那样,
functools.partial
可能是一条出路

但是,可以使用curried函数完成类似的工作:

def multiply_by(multiplier):
    def multiply(x):
        return multiplier * x
    return multiply

>>> multiply_by_5 = multiply_by(5)    # no magic
>>> multiply_by_5(2)
10
或者使用lambda语法:

def multiply_by(multiplier):
    return lambda x: multiplier * x
请注意,
partial
更简洁、更高效,并且更直接地以标准方式表达您的意图。上述技术是闭包概念的一个例子,这意味着在内部作用域中定义的函数可以引用在封闭作用域中定义的变量,并在其上“关闭”,记住它们,甚至对它们进行变异

由于这种技术更加通用,代码的读者可能需要更多的时间来理解代码中的确切含义,因为您的代码可能任意复杂


专门用于乘法(和其他运算符)
partial
可以与
运算符组合。mul

>>> import functools, operator
>>> multiply_by_5 = functools.partial(operator.mul, 5)
>>> multiply_by_5(2)
10

这里有一个不使用
functools.partial
的替代方案。相反,我们在函数中定义一个函数。内部函数“记住”它需要的外部函数的任何局部变量(包括外部函数的参数)。让这一切发生的魔法叫做

输出

0 0 0
1 3 5
2 6 10
3 9 15
4 12 20
如果需要,可以在闭包中使用现有的
multiply\u by
函数,尽管由于额外函数调用的开销,效率稍低。例如:

def multiply_factory(multiplier):
    def fixed_multiply(x):
        return multiply_by(x, multiplier)
    return fixed_multiply
可以使用
lambda
语法更简洁地编写:

def multiply_factory(multiplier):
    return lambda x: multiply_by(x, multiplier)

使用乘以5(x)比乘以(x,5)有什么好处?当然,使用a。或者创建一个不称为复制的文件,因为实际上没有复制任何内容。这叫做“部分应用”。一个相关的概念是“curried function”。与定义另一个函数(最终与
lambda
内联)相比,有什么优势吗?@norok2:这里没有太大的区别,但请参阅详细答案。在这种情况下,性能差异似乎并不相关,但我不确定更复杂的情况。就优雅而言,我看不出这里有什么主要优势,但我承认情况并非总是如此。。但感谢@niemmi指出了那个有趣的讨论。这不仅仅是优雅。它更多的是使用标准的、熟悉的和可预测的工具,而不是一些需要阅读和理解的任意代码。谢谢。我不知道那个模块。很高兴知道,谢谢。很好的例子。我不知道有人能做到。关于python的一些知识。这已经是美好的一天了;)
def multiply_factory(multiplier):
    def fixed_multiply(x):
        return multiply_by(x, multiplier)
    return fixed_multiply
def multiply_factory(multiplier):
    return lambda x: multiply_by(x, multiplier)