【发布时间】:2015-08-01 00:27:05
【问题描述】:
在末尾添加使用上下文
我经常想对列表等抽象对象进行操作。例如
def list_ish(thing):
for i in xrange(0,len(thing)):
print thing[i]
现在,如果 thing 是一个列表,这是合适的,但如果 thing 是一个 dict 则将失败。 pythonic 为什么要问“你表现得像一个列表吗?”
注意:
hasattr('__getitem__') and not hasattr('keys')
这适用于我能想到的所有情况,但我不喜欢消极地定义鸭子类型,因为我预计可能会有它无法捕捉到的情况。
我真正想问的是。
“嘿,你是否像我期望的列表那样对整数索引进行操作?”例如
thing[i], thing[4:7] = [...], etc.
注意:我不想简单地在大型 try/except 中执行我的操作,因为它们具有破坏性。在这里尝试失败并不酷......
使用背景 --“点列表”是一个类似列表的东西,它包含类似字典的东西作为它的元素。 -- 一个“矩阵”是一个类似列表的东西,包含类似列表的东西
-- 我有一个函数库,可以在点列表上运行,也可以在类似矩阵的东西上以类似的方式运行。
——例如,从用户的角度来看,破坏性操作,如“电子表格”操作“列切片”可以以类似的方式对矩阵对象和点列表对象进行操作——结果东西和原来的一样,但只有指定的列。
-- 因为这个特定的操作是破坏性的,所以如果一个对象是一个矩阵来进行,只是在操作的一部分中发现,它实际上是一个点列表或者不是--以上。
-- 我希望我的 'is_matrix' 和 'is_point_list' 测试是高效的,因为它们有时会发生在内部循环中。因此,我会对仅调查零元素的测试感到满意。
-- 我更喜欢不涉及构建临时对象的测试,只是为了确定对象的类型,但也许这不是 python 的方式。
总的来说,我发现整个鸭子打字有点乱,并且充满了错误和缓慢,但也许我还没有像真正的 Pythonista 那样思考
很高兴喝更多的酷爱...
【问题讨论】:
-
在 Python 中进行 Duck Typing 的公认方法是将其视为鸭子,然后使用 try/except 来发现它不起作用。您能否更详细地说明一下您认为这对您的情况不起作用的原因?
-
只检查
thing的类型?例如。 stackoverflow.com/questions/1835018/… -
你只是想快速失败吗?或者你真的需要确定类型吗?如果有人传入了一个没有派生
list的鸭式“列表”,那么您需要多少list功能,或者期望他们会实现多少? -
马上开始,使用
for item in thing: print item比迭代一系列索引更符合Pythonic。 -
@dagetz 就像 'sort' 不返回任何值,而是直接修改它正在排序的列表,我的 column_slice 操作修改了点列表中的所有点,或者它修改了矩阵中的内部列表。所以它是破坏性的——我的用例是对非常大的数据集进行串行操作,所以就像 numpy 模块一样,我允许用户就地修改这些结构,并要求他们显式复制它们,当他们想要分离效果时从另一个地方的动作中放置。