[英]Is it a natural design pattern to use closures and dynamically defined functions in Python?
[英]Can one use closures to simplify functions in Python?
想象一下,如果你想创建一个闭包函数来决定它的内部函数做什么的一些选项。 在这个例子中,我们有一个内部函数来决定一个数是否是偶数,但是生成器决定数字是否是偶数,好像有争论一样。
def generate_is_even(reject_zero):
def is_even(x):
return (x % 2 == 0 and x != 0) if reject_zero else x % 2 == 0
return is_even
如果is_even(x)运行数百万次,则每次运行is_even(x)时仍会检查reject_zero! 我的实际代码有许多类似的“选项”来创建一个运行数百万次的函数,并且为每个选项组合编写函数会很不方便。 有没有办法防止这种低效率,或者Python的某些实现是否简化了这一点?
你似乎在寻找像C中的宏一样的东西。不幸的是,Python没有被编译(与纯粹主义者的C不同),我没有看到直接的解决方案来满足你的需求。
您仍然可以在运行时开始设置所有参数,并根据参数值选择此时的功能。 例如,您的函数生成器将类似于:
def generate_is_even(reject_zero):
def is_even_true(x):
return (x % 2 == 0 and x != 0)
def is_even_false(x):
return x % 2 == 0
return (is_even_true if reject_zero else is_even_false)
def setup(reject_zero, arg2, arg3):
is_even = generate_is_even(reject_zero)
这种情况的强烈反应是必须为处理这种参数的每个函数编写一个生成器。 在你提出的情况下,这不是一个大问题,因为只有两个版本的函数,不是很长。
你需要问问自己什么时候这样做有用。 在您的情况下,只有一个布尔比较,这不是真正的资源消耗,但可能存在以前生成函数可能变得有价值的情况。
考虑在列表中缓存所有选项,生成的函数只迭代所选的函数
def generate_is_even(**kwargs):
options = {'reject_zero': lambda x: x != 0}
enabled = [options[o] for o in options if o in kwargs and kwargs[o]]
def is_even(x):
return all([fn(x) for fn in enabled]) and x % 2 == 0
return is_even
然后你可以使用
is_even_nozero = generate_is_even(reject_zero=True)
is_even_nozero(0) # gives False
is_even = generate_is_even()
is_even(0) # gives True
如果你需要添加选项然后将它添加到选项dict
,你可以使用new_option=True
是generate_is_even函数来启用它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.