python - 在 python 中,拦截属性

  显示原文与译文双语对照的内容
0 0

我无法找到要搜索的内容,所以如果已经在那里,我会先对它的进行搜索。

有些背景:我正在为提供一些额外的功能,而我希望能够在单个调用中对单元格区域应用样式。 现在,我们的代码允许我们做一些类似 ws[1][1].font.bold = True的事情,以加粗单元格 A1. 我们还有一个范围操作符,允许我们做一些类似 ws.range("A1:B2").value = 1的事情,把这个范围内的所有值设置为 1.

现在我想要做的是添加 ws.range("A1:B2").font.bold = True的能力,但是我不知道。 range("A1:B2") 是不显式引用单元的( 只有两个角可以节省空间),但没有显式地拥有 .font 或者 .value 属性的对象,而是通过 @property decorator进行拦截,以适当地应用它。

如果在属性中添加一个 font 属性,我就可以返回一个新的字体对象,但是在修改属性之后,我没有办法将它应用到区域中的所有单元格。

我想我可以在 yield 之后添加字体,然后在 yield 之后添加应用逻辑,但 yield 返回一个生成器不起作用。 我能想到的其他想法是创建显式的.font 对象,然后在 Range 类中重写 .font.__setattr__ 以侦听更改,但是在不需要创建第三个中间类的情况下,我无法确定如何使用。 这不仅看起来相当笨拙,而且看起来是难以置信的unpythonic 。

如果不需要得到深奥的方法,就像这样? 我希望我的解释是明确又重要的,如果已经出现,请随时指向我一个现有的参考 -- 。

时间: 原作者:

0 0

要扩大我的评论,你应该做如下事情:


class RangeFont(object):

 def __init__(self, range):
 self._range = range

 def __setattr__(self, name, value):
 if name.startswith('_'):
 super(RangeFont, self).__setattr__(name, value)
 return

 for cell in self._range: # assuming a range is iterable
 setattr(cell.font, name, value)


class Range(object):
 @property
 def font(self):
 return RangeFont(self)

上面代码的限制是,它不能对属性的进一步级别进行操作,即你不能执行 ws.Range(...).font.foo.bar = 123 。 ( 这表示你可以通过 RangeFont.__getattr__ 返回类似的包装对象来扩展它。)

原作者:
...