假设我有以下函数返回一个函数:
def make_square_matrix_creator(dim):
mat = np.zeros([dim, dim])
def square_matrix_creator(value):
mat += value
return mat
return square_matrix_creator
现在,此代码不起作用,因为内部函数无法访问mat
。
f = make_square_matrix_creator(4)
f(3)
UnboundLocalError: local variable 'mat' referenced before assignment
我知道有几种方法可以解决这个问题;我可以mat
全球:
def make_square_matrix_creator(dim):
global mat
mat = np.zeros([dim, dim])
def square_matrix_creator(value):
global mat
mat += value
return mat
return square_matrix_creator
它有效,但是它具有与在函数中创建全局对象相关的所有问题
我可以将mat作为默认参数传递给内部函数;
def make_square_matrix_creator(dim):
mat = np.zeros([dim, dim])
def square_matrix_creator(value, mat=mat):
mat += value
return mat
return square_matrix_creator
但是当我在现实世界的例子中尝试这一点时,我遇到了可变默认值的问题。是否有其他选项可以让内部函数访问在其父函数中创建的对象?
答案 0 :(得分:0)
对于Python 2.7,您可以使用[:]
来指示嵌套函数中的就地变异。示例 -
def make_square_matrix_creator(dim):
mat = np.zeros([dim, dim])
def square_matrix_creator(value):
mat[:] = mat + value
return mat
return square_matrix_creator
我在Python 3.4中对此进行了测试(遗憾的是,我没有使用numpy来测试它的Python 2.7,我使用普通列表在Python 2.7中进行了测试,它适用于普通列表)。演示 -
In [50]: def make_square_matrix_creator(dim):
....: mat = np.zeros([dim, dim])
....: def square_matrix_creator(value):
....: mat[:] = mat + value
....: return mat
....: return square_matrix_creator
....:
In [53]: f = make_square_matrix_creator(4)
In [54]: f(3)
Out[54]:
array([[ 3., 3., 3., 3.],
[ 3., 3., 3., 3.],
[ 3., 3., 3., 3.],
[ 3., 3., 3., 3.]])
答案 1 :(得分:0)
您可以尝试创建别名。
# This class is a minimally working shim for the numpy object
# because I don't want to import the full numpy package.
class K(object):
def __init__(self, other):
self.v = other
def __iadd__(self, other):
self.v += other
def outer(x):
mat = K(x)
def inner(y):
alias = mat # Create alias to mutable object. alias is now modifiable
alias += 1 # Modify alias to work around Python 2.x limitation.
return mat
return inner
>>> f = outer(5)
>>> res = f(1)
>>> res
<__main__.K at 0x102acb1d0>
>>> res.v
6
>>> f(1)
<__main__.K at 0x102acb1d0>
>>> res.v
7