简体   繁体   English

在python中生成没有闭包的函数

[英]Generate functions without closures in python

right now I'm using closures to generate functions like in this simplified example: 现在我正在使用闭包来生成像这个简化示例中的函数:

def constant_function(constant):
    def dummyfunction(t):
        return constant
    return dummyfunction

These generated functions are then passed to the init-method of a custom class which stores them as instance attributes. 然后将这些生成的函数传递给自定义类的init方法,该类将它们存储为实例属性。 The disadvantage is that that makes the class-instances unpickleable. 缺点是这使得类实例难以理解。 So I'm wondering if there is a way to create function generators avoiding closures. 所以我想知道是否有办法创建函数生成器来避免闭包。

You could use a callable class: 你可以使用一个可调用的类:

class ConstantFunction(object):
    def __init__(self, constant):
        self.constant = constant
    def __call__(self, t):
        return self.constant

def constant_function(constant):
    return ConstantFunction(constant)

The closure state of your function is then transferred to an instance attribute instead. 然后,函数的闭包状态将转移到实例属性。

Not that I'd recommend this for general use… but there's an alternate approach of compiling and exec 'ing the code. 并不是说我推荐这个用于一般用途......但是有一种编译和exec代码的替代方法。 It's generating a function w/oa closure. 它正在生成一个没有闭包的函数。

>>> def doit(constant): 
...   constant = "def constant(t):\n  return %s" % constant
...   return compile(constant, '<string>', 'exec')
... 
>>> exec doit(1)
>>> constant(4)
1
>>> constant

Note that to do this inside an enclosing function or class (ie not in the global namespace) you have to also pass in the appropriate namespace to exec . 请注意,要在封闭函数或类中(即不在全局命名空间中)执行此操作,您还必须将适当的命名空间传递给exec See: https://docs.python.org/2/reference/simple_stmts.html#the-exec-statement 请参阅: https//docs.python.org/2/reference/simple_stmts.html#the-exec-statement

There's also the double lambda approach, which is not really a closure, well, sort of… 还有双lambda方法,它不是真正的闭包,嗯,有点......

>>> f = lambda x: lambda y:x
>>> g = f(1)
>>> g(4)
1
>>> import dill
>>> _g = dill.dumps(g)
>>> g_ = dill.loads(_g) 
>>> g_(5)
1

You seemed worried about the ability to pickle closure-like objects, so you can see even the double lambdas are pickleable if you use dill . 你似乎担心腌制类似闭合的物体的能力,所以如果你使用dill ,你甚至可以看到双羔羊是可腌制的。 The same for class instances. 类实例也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM