nic*_*ick 6 python methods metaprogramming class
我有一个类,我想为列表的每个元素初始化一个属性self.listN和一个add_to_listN方法,例如从attrs = ['list1', 'list2']我想要list1并list2初始化为空列表和方法add_to_list1以及add_to_list2要创建的方法.每个add_to_listN方法应该采用两个参数,比如说value和unit,并将一个元组附加(value, unit)到相应的参数listN.
因此,该类最终应该是这样的:
class Foo():
def __init__(self):
self.list1 = []
self.list1 = []
def add_to_list1(value, unit):
self.list1.append((value, unit))
def add_to_list2(value, unit):
self.list2.append((value, unit))
Run Code Online (Sandbox Code Playgroud)
撇开所有支票和课堂上的其他人,我想出了这个:
class Foo():
def __init__(self):
for attr in ['list1', 'list2']:
setattr(self, attr, [])
setattr(self, 'add_to_%s' % attr, self._simple_add(attr))
def _simple_add(self, attr):
def method(value, unit=None):
getattr(self, attr).append((value, unit))
return method
Run Code Online (Sandbox Code Playgroud)
我还检查了其他解决方案,例如这里建议的解决方案,我想"正确",所以我的问题是:
classmethod?__init__,在这种情况下是否有替代方案?for循环并添加这些方法的最佳位置在哪里?在类定义中?出来的?更新
虽然Benjamin Hodgson提出了一些好处,但我并不是要求一种(或许更好的)替代方法来做到这一点,而是为了使用我提到的工具的最佳方式.我正在使用一个简化的例子,以便不关注细节.
为了进一步澄清我的问题:这些add_to_listN方法是额外的,而不是取代setter/getters(所以我仍然希望能够做到l1 = f.list1和f.list1 = []使用f = Foo()).
你犯了一个设计错误。您可以重写__getattr__、解析属性名称,并返回一个执行您想要的操作的闭包,但是动态生成方法很奇怪,奇怪的代码就是糟糕的代码。经常有一些情况需要您这样做,但这不是其中之一。
与其生成对n其中一个n对象执行相同操作的方法,为什么不只编写一个由 参数化的方法呢n?大致是这样的:
class Foo:
def __init__(self):
self.lists = [
[],
[]
]
def add(self, row, value):
self.lists[row].append(value)
Run Code Online (Sandbox Code Playgroud)
那么就foo.add1(x)变得简单foo.add(1, x);foo.add2(x)变为foo.add(2, x),等等。有一种方法,沿着变化轴参数化,适用于所有情况 - 而不是一长串临时生成的方法。简单多了。
| 归档时间: |
|
| 查看次数: |
243 次 |
| 最近记录: |