假设variable = None
,如何以编程方式区分以下切片语法(具有相同的效果)?
obj[variable:]
obj[variable:None]
obj[:variable]
obj[None:variable]
obj[:]
obj[::]
obj[None:None]
obj[None:None:None]
我正在尝试自定义 __getitem__
我的类的方法[ab]使用切片语法进行高级索引(语法糖),并且希望以不同的方式处理不同的切片语法,因为我需要大量语法糖...(这可能是这不是一个好的做法,只是用于实验......)。
def __getitem__(self, slice_obj):
# slice_obj will be `slice(None, None, None)` for all
# `obj[variable:]`, `obj[:variable]` and `obj[:]`
我们可以看到使用dis
有不同的切片操作码图书馆:
https://docs.python.org/2/library/dis.html#opcode-SLICE+0
SLICE+0() Implements TOS = TOS[:].
SLICE+1() Implements TOS = TOS1[TOS:].
SLICE+2() Implements TOS = TOS1[:TOS].
SLICE+3() Implements TOS = TOS2[TOS1:TOS].
那么任何人都可以使用一些内省(introspection)技巧来区分不同的语法(inspect, dis, ast,
等)吗?
进一步问题:
如何区分函数中的传入参数和默认参数?例如,
def add(x, delta=1):
return x + delta
内部add
函数,我们如何判断它是否被称为 add(x)
或add(x, 1)
?
链接:
[我们可以为切片使用唯一的、不同的默认参数(除了 None 之外)吗?]
https://docs.python.org/2/c-api/slice.html#c.PySlice_New http://www.boost.org/doc/libs/1_39_0/libs/python/doc/v2/object.html#slice_nil-spec
任何评论/解决方法/黑客都表示赞赏!
最佳答案
给定 slice
对象,无法确定使用什么类型的索引表达式来创建它。 slice
这是从 a[:14]
创建的与 a[None:14]
创建的没有区别或字面量 slice(None, 14)
.
如果您想要变得有点困惑(并且非常不可移植),那么您可能可以通过查看父框架中的当前操作码来获得一些可靠的结果:
import sys, dis
class Moo(object):
def __getitem__(self, i):
parent_frame = sys._getframe().f_back
accessing_opcode = parent_frame.f_code.co_code[parent_frame.f_lasti]
return "This __getitem__ was invoked by way of a %s instruction" \
% dis.opname[ord(accessing_opcode)]
这会产生如下结果:
>>> m = Moo()
>>> m[5]
'This __getitem__ was invoked by way of a BINARY_SUBSCR instruction'
>>> m[5:]
'This __getitem__ was invoked by way of a SLICE+1 instruction'
>>> m[:5]
'This __getitem__ was invoked by way of a SLICE+2 instruction'
>>> m[5:5]
'This __getitem__ was invoked by way of a SLICE+3 instruction'
>>> m[:5:]
'This __getitem__ was invoked by way of a BINARY_SUBSCR instruction'
>>> m[1:5:2]
'This __getitem__ was invoked by way of a BINARY_SUBSCR instruction'
显然,如果您的 __getitem__
的话,这就没那么有用了。方法被显式调用,但也许它可以满足您的需求。
关于Python slice 如何区分切片参数和默认参数(例如,x[i :] vs. x[i :None])?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35179953/