我正在研究一個需要採用任意Python對象的方法的項目,並且該對象的行爲類似於dict
,list
或tuple
--這意味着它支持通過鍵或索引 - 我的方法應該返回一個可以遍歷對象的鍵值或索引值對的迭代器。如果迭代器只是遍歷對象鍵或索引,那對我的目的也是可以的。下面是到目前爲止,我已經得到了代碼:如何獲得遍歷任意Python對象的鍵/索引的迭代器?
from collections import Mapping, Sequence
# Tuple used to identify string-like objects in Python 2 or 3.
STRINGS = (str, unicode) if str is bytes else (str, bytes)
def get_keyval_iter(obj):
if isinstance(obj, STRINGS): return None
elif isinstance(obj, Sequence): return enumerate(obj)
elif isinstance(obj, Mapping): return getattr(obj, 'iteritems', obj.items)()
else: return None
# For example:
print list(get_keyval_iter([0, 11, 22])) # [(0, 0), (1, 11), (2, 22)]
print list(get_keyval_iter(dict(a = 1, b = 2))) # [('a', 1), ('b', 2)]
print [ get_keyval_iter("foobar") ] # [None]
print [ get_keyval_iter(1234) ] # [None]
我不喜歡有兩個原因此解決方案:(1)一般原則,我寧願查詢對象的接口不是檢查它的類型; (2)我的代碼將返回None
用於用戶定義的類,其對象未通過isinstance
測試但支持__getitem__
協議,並且理論上可以給我一個有關鍵或索引的迭代器。
下面是我想寫的代碼:return obj.__getitemiter__()
- 或類似的東西。
我是否忽視了一種顯而易見的方式來獲得我所需要的 - 即對任意對象的鍵或索引(或通過其鍵值或索引值對)的迭代器?
@FMc:所以你是;我的觀點是任何可迭代的東西都應該支持'iter()'。 –
@FMc:'iter()'上的'enumerate()'不起作用? –
有*總是*限制什麼可以實現。如果一個對象沒有提供所有被識別爲映射的方法,那麼它就是一個序列,除非它甚至沒有'__getitem__'方法。這是它應該結束的地方。 –