对不起,标题写得不好。我希望一个简单的例子能说明这一点。下面是我想做的最简单的方法:
class Lemon(object):
headers = ['ripeness', 'colour', 'juiciness', 'seeds?']
def to_row(self):
return [self.ripeness, self.colour, self.juiciness, self.seeds > 0]
def save_lemons(lemonset):
f = open('lemons.csv', 'w')
out = csv.writer(f)
out.write(Lemon.headers)
for lemon in lemonset:
out.writerow(lemon.to_row())
对于这个小例子来说,这很管用,但我觉得我在柠檬课上“重复我自己”。而在我试图编写的实际代码中(我要导出的变量数量是~50而不是4个,并且where to\u row调用了许多执行一系列奇怪计算的私有方法),这就变得很尴尬了。你知道吗
在编写生成行的代码时,我需要不断引用“headers”变量,以确保以正确的顺序构建列表。如果我想更改输出的变量,我需要确保行和头是并行更改的(这正是DRY要防止的,对吧?)。你知道吗
有没有更好的方法来设计这个代码?我一直在玩函数装饰,但没有什么坚持。理想情况下,我应该仍然能够在没有特定lemon实例的情况下获取标题(即,它应该是一个类变量或类方法),并且我不希望每个变量都有一个单独的方法。你知道吗
我们可以用元类shenanegans来做这个。。。你知道吗
在Python2中,属性在dict中传递给元类,而不是 为了保持顺序,我们还需要一个基类来处理 区分应映射到行中的类属性。在python3中,我们可以省去几乎所有的基描述符类。你知道吗
我们需要一个python描述符来描述我们希望映射到 行。slot是一种很好的获取数据描述符的方法,不需要做很多工作。一个 不过,需要注意的是,我们必须手动删除helper实例才能使 实插槽描述符可见。你知道吗
对于计算字段,我们可以记忆结果。注释的回忆录 如果没有内存泄漏,实例很棘手,我们需要weakref。或者,我们 可以安排另一个插槽来存储缓存的值。这也不是很线程安全,但非常接近。你知道吗
在元类上,我们在上面创建的所有描述符都是按 创建顺序,并指示对新创建的类进行注释。确实如此 不能正确处理派生类,并且可以使用其他一些便利,如 所有插槽的
__init__
。你知道吗最后,我们希望从中继承一个基类,这样就可以有一个
to_row
方法。这只会调用所有__get__
的 描述符,按顺序。你知道吗假设所有这些都隐藏起来,看不见,一个类的定义 使用此功能的用户基本上不需要重复。唯一的捷径就是 为了实用,每个字段都需要一个python友好的名称,因此我们有了
alias
键将'seeds?'
关联到has_seeds
在本例中,
getattr()
是您的朋友:它允许您根据字符串名称获取变量。例如:编辑:要正确使用头
seeds?
,需要为对象设置属性seeds?
。setattr(self, 'seeds?', self.seeds > 0)
在return语句的正上方。你知道吗相关问题 更多 >
编程相关推荐