为无益的头衔道歉,但我不知道如何在一个引人注目的单行中表达我的问题。让我解释一下。
在Common Lisp等语言中,您可以使用闭包来“隐藏全局变量”,如
(let ((my-global-variable '(foo bar))))
(defun f (x) (append my-global-variable x)))
这样做的预期效果是
其中'隐形'应该带有一粒盐,因为仍然可以使用依赖于实现的检查设施从外部访问变量。因此,让我们同意“隐形”的意思是“不影响变量的全局命名空间”。
在Python中实现1.和2.的一种可能方法是:
def helper_function():
my_global_variable = ['foo', 'bar']
def f(x):
return my_global_variable + x
return f
f = helper_function()
评估f(['baz'])
按预期返回['foo', 'bar', 'baz']
,并且它满足1.和2.但是与Lisp版本相比,它不是真的
取决于您使用的是Python< = 2(no)还是Python 3(是)。由于我的意图是在这个变量中存储计算成本高的对象,因此可变性并不重要。 但除此之外,上述解决方案还存在其他问题。
更确切地说,我问是否还有其他解决方案
helper_function
)
以下是答案列表,这些答案来自user2357112,CircArgs和Stefan Pochmann的有用评论。
解决方案1:可调用对象(满足1-3)
class helper_class:
my_global_var = ['foo','bar']
def __call__(self, x):
return self.my_global_var + x
f = helper_class()
解决方案2:默认值为可选参数(满足1,2,4,5(或2,3,4,5;见下文))
def f(x, my_global_var=['foo', 'bar']):
return my_global_var+x
请注意,变量是可变的,但突变不会在函数调用之间延续,因此它不会同时满足1和3。另请注意,默认参数仅评估一次(定义函数时),因此我可以接受。
解决方案3:功能属性(满足1-5)
def f(x):
return f.my_global_var + x
f.my_global_var = ['foo', 'bar']
从技术上讲,这是最好的解决方案(满足所有要求),但它比使用默认参数稍微冗长。
解决方案4:聪明的命名空间Hack (满足1,2,5)
def f():
my_global_var = ['foo', 'bar']
def f(x):
return my_global_var + x
return f
f = f()
请注意,返回的f
实际上是内部的,不是的外部。
答案 0 :(得分:1)
也许你正在寻找那种东西。我认为它比试图与Python搏斗以获得纯粹的功能性行为更加pythonic:
class Helper:
__hidden_var=5
def __init__(self):
pass
def __call__(self, x):
self.__hidden_var=x
我有点武断,因为我不完全确定你想要什么,但我已经按照你的要求演示了一个可调用的对象。请注意,__
在实例实例化后使实例外部的属性不可访问(尽管这不是完全为真,因为您仍然可以使用instance._Helper__hidden_var获取它)。您可以选择使用辅助函数之类的东西来真正隐藏这样的变量。您可以轻松实现另一种方法来编辑隐藏变量encapsulation