首先说我是python的新手,我使用的是python版本3.6.5 我不太喜欢python将函数输入作为“对象引用”处理的方式。
这里给出的例子非常简单,只是为了说明我的观点。
这是我正在运行的第一个代码(错误的行为):
integer = 0
def func(t): return integer
class FooClass(object):
def __init__(self, input_function):
self.function = input_function
def give_value(self, index):
print(self.function(index))
foo_object = FooClass(func)
foo_object.give_value(0)
# Output >> 0
integer = 1
foo_object.give_value(0)
# Output >> 1
我希望我的FooClass对象完全独立于外部变化。
这是我正在运行的第二个代码(正确行为):
integer = 0
def step_function(integer_input):
def func(t): return integer_input
return FooClass(func)
class FooClass(object):
def __init__(self, input_function):
self.function = input_function
def give_value(self, index):
print(self.function(index))
foo_object = step_function(integer)
foo_object.give_value(0)
# Output >> 0
integer = 1
foo_object.give_value(0)
# Output >> 0
我很满意,但我不明白为什么会这样。实际上,我担心我的self.function引用了step_function调用期间定义的'integer_input'。所以它引用了一个可以覆盖的可用内存空间(如果在python中有任何意义)。
提前致谢!
答案 0 :(得分:0)
因此,要解释为什么您的代码的功能不同:ERR_CONNECTION_REFUSED
是一个引用整数的名称。在您的第一个示例中,您在integer
中使用此名称,这将创建一个闭包,该闭包从全局范围中包含对func
的引用并将其传递。因此,所有将来的调用都会引用全局范围内名称integer
所持有的内容。
在第二个示例中,您创建了新名称integer
以引用integer_input
并引用integer
中的integer_input
。这会创建一个闭包,用于封装 function 范围内对func
的引用并将其传递。
如果你能以某种方式改变integer_input
范围内引用的integer_input
,你会遇到同样的问题,但这很难做到(而且几乎不可能无意中做到)。
如果您希望更新第一个示例以按预期工作,则可以使用以下代码:
step_function
这会手动创建一个闭包,以将名称 func = (lambda value: lambda t: value)(integer)
与integer
引用的对象分离,类似于您的第二个示例。
或者,要更新当前的结构以执行类似的操作:
integer
请注意,这两种方法是等效的,只是语法不同。