动态添加属性会创建不需要的别名
adding properties dynamically creates unwanted aliases
我想按如下方式将属性动态添加到我的 class,但是我最终创建了别名。我怎样才能避免这种情况?
class A:
def __init__(self, a, b):
self._a = a
self._b = b
for attr in ('a', 'b'):
f = lambda self: getattr(self, '_'+attr)
setattr(A, attr, property(f, None))
a = A(0,1)
print(a.a)
print(a.b)
但是这会产生:
1
1
编辑:
关于闭包作用域的评论是相关的,但这留下了一个问题,即是否可以动态生成引用 self open 的某些属性的属性。
特别是关于上面的例子:我如何设置 属性 使得 a.a returns 0 而不是 1?如果我只是尝试将属性参数传递给 lambda 函数,则需要传递此属性,因此这将不起作用。
为了获得所需的结果,您需要将 lambda 包装在另一个函数中,如下所示:
def make_fget(attr):
return lambda self: getattr(self, '_' + attr)
这样,当您调用 make_fget
时,本地名称 attr
绑定到传递的参数。
您可以像在原始代码中一样在循环中调用它:
for attr in ('a', 'b'):
setattr(A, attr, property(make_fget(attr), None))
这里的区别在于,在您的原始版本中,循环本质上是在每次迭代时重新分配 attr
,而 lambda 当时仅在外部范围(循环)中查看 attr
它被调用,它将以上次迭代中分配的任何内容结束。
通过包装在另一个函数中,在每次循环迭代中,您实际上为返回的 lambda 创建了一个新的外部作用域(函数调用),名称 attr
绑定到传递的参数。
我想按如下方式将属性动态添加到我的 class,但是我最终创建了别名。我怎样才能避免这种情况?
class A:
def __init__(self, a, b):
self._a = a
self._b = b
for attr in ('a', 'b'):
f = lambda self: getattr(self, '_'+attr)
setattr(A, attr, property(f, None))
a = A(0,1)
print(a.a)
print(a.b)
但是这会产生:
1
1
编辑:
关于闭包作用域的评论是相关的,但这留下了一个问题,即是否可以动态生成引用 self open 的某些属性的属性。
特别是关于上面的例子:我如何设置 属性 使得 a.a returns 0 而不是 1?如果我只是尝试将属性参数传递给 lambda 函数,则需要传递此属性,因此这将不起作用。
为了获得所需的结果,您需要将 lambda 包装在另一个函数中,如下所示:
def make_fget(attr):
return lambda self: getattr(self, '_' + attr)
这样,当您调用 make_fget
时,本地名称 attr
绑定到传递的参数。
您可以像在原始代码中一样在循环中调用它:
for attr in ('a', 'b'):
setattr(A, attr, property(make_fget(attr), None))
这里的区别在于,在您的原始版本中,循环本质上是在每次迭代时重新分配 attr
,而 lambda 当时仅在外部范围(循环)中查看 attr
它被调用,它将以上次迭代中分配的任何内容结束。
通过包装在另一个函数中,在每次循环迭代中,您实际上为返回的 lambda 创建了一个新的外部作用域(函数调用),名称 attr
绑定到传递的参数。