在python 3.x中,我試圖實現一個類,該類將作爲參數給出的序列的代理。該代理還使用在輸入序列的每個元素上調用的函數。代理類可以是可索引或可迭代的序列
代理類根據輸入序列中的可用性動態實現__getitem__
,__iter__
和__len__
方法的正確方法是什麼?這是我在做這個(我打電話給我的序列「供應商」,功能是「改造」)的嘗試:
class TransformProviderProxy:
def __init__(self, input_provider, transform):
self.input_provider = input_provider
self.transform = transform
def __iter__(self):
# Use generator expressions to produce a new iterator when requested
return (self.transform(data_sample) for data_sample in self.input_provider)
def __getattr__(self, name):
if name == "__getitem__" and hasattr(self.input_provider, "__getitem__"):
return self._getitem_impl
elif name == "__len__" and hasattr(self.input_provider, "__len__"):
return self._len_impl
else:
return None
def _getitem_impl(self, index):
return self.transform(self.input_provider[index])
def _len_impl(self):
return len(self.input_provider)
但是失敗,因爲它似乎是蟒蛇尋找__getitem__
時繞過__getattr__
。什麼是正確的方法來做到這一點?
作爲獎勵,有沒有辦法做到這一點,而我的代理類動態地從collections.abc.Sequence
或collections.abc.Iterable
繼承取決於輸入序列?
PS:我也考慮過只是在實現__getitem__
時,依靠捕獲TypeError來嘗試在非可索引輸入序列上調用它時,但我希望能夠通過查找來檢查我的代理類是否可索引__getitem__
的存在,而不必使用索引顯式調用它。
我編輯我的問題,你發佈之前你的答案很抱歉(你太對我來說很快!)。我曾考慮過這個問題,但我希望能夠檢查我的類是否可以索引(理想情況是通過檢查它是否是'collections.abc.Sequence'的一個實例),而不必明確嘗試索引它。也許我應該接受你的方式是更pythonic的方式? –
是的,[EAFP(容易請求寬恕而不是權限)](https://docs.python.org/3/glossary.html#term-eafp)被認爲比[LBYL(在你跳躍之前看)更「pythonic」 ](https://docs.python.org/3/glossary.html#term-lbyl)。不過,您可能需要簽出第三方模塊['wrapt',它是'ObjectProxy'](http://wrapt.readthedocs.io/en/latest/wrappers.html#proxies-and-wrappers)。這可能包含一些(已建成的)解決方案,以解決您的緊急問題。對不起,我沒有看到你之前的最後一段...... :( – MSeifert