Python切片如何区分切片参数和默认参数(例如,x[i:]与x[i:None])?
假设Python切片如何区分切片参数和默认参数(例如,x[i:]与x[i:None])?,python,indexing,syntax,slice,default-arguments,Python,Indexing,Syntax,Slice,Default Arguments,假设variable=None,如何通过编程区分以下切片语法(具有相同的效果) 我正在尝试自定义我的类的\uu getitem\uuuu方法,以[ab]使用切片语法进行高级索引(语法糖),并希望以不同的方式对待不同的切片语法,因为我需要大量的语法糖…(这可能不是一个好的实践,但仅用于实验…) 我们可以使用dis库看到不同的切片操作码: SLICE+0()实现TOS=TOS[:] SLICE+1()实现TOS=TOS1[TOS:] SLICE+2()实现TOS=TOS1[:TOS] SLICE+
variable=None
,如何通过编程区分以下切片语法(具有相同的效果)
我正在尝试自定义我的类的\uu getitem\uuuu
方法,以[ab]使用切片语法进行高级索引(语法糖),并希望以不同的方式对待不同的切片语法,因为我需要大量的语法糖…(这可能不是一个好的实践,但仅用于实验…)
我们可以使用dis
库看到不同的切片操作码:
SLICE+0()实现TOS=TOS[:]
SLICE+1()实现TOS=TOS1[TOS:]
SLICE+2()实现TOS=TOS1[:TOS]
SLICE+3()实现TOS=TOS2[TOS1:TOS]
因此,任何人都可以使用一些内省黑客来告诉不同的语法(inspect、dis、ast、
等)
进一步问题:
如何区分函数中的传入参数和默认参数?例如:
def add(x, delta=1):
return x + delta
在add
函数中,我们如何判断它是被称为add(x)
还是add(x,1)
链接:
[我们是否可以为slice使用唯一的、不同的默认参数(None除外)?]
任何意见/解决方法/黑客都将不胜感激 对于确定调用函数的第二部分:
import inspect
>>> def add(a, b=0):
... return a + b
...
>>> inspect.getargspec(add)
(['a', 'b'], None, None, (0,))
>>> len(inspect.getargspec(add)[0])
2
给定一个
切片
对象,无法确定用于创建它的索引表达式的类型。从a[:14]
创建的slice
与由a[None:14]
或literalslice(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'
显然,如果显式调用\uuuu getitem\uuu
方法,这将没有多大帮助,但它可能会满足您的需要。感谢@chepner指出。我试着用slice作为语法糖,我需要很多糖来表达不同的意思。。。我更新了我的问题来强调这一点。非常小心地滥用标准语法-确保当你的切片/切片背叛了正常使用时,你的API聪明度超过了任何用户认知上的不一致,特别是在那些刚刚搞清楚切片是怎么回事的新pythoner中。另外,您的API将如何处理本身是切片对象的单个参数?谢谢,我将阅读更多关于检查和试验您的方法的信息。您也可以将参数默认为某个抽象值,检查该值,如果它仍然是抽象的,则将其设置为正确的默认值!如果你有几个论点,这可能会很长!def add(a,b=6996420):如果b==6996420:b=1返回a+By,您可能在不同版本的Python中也存在问题。感谢您检查操作码的方法!这是我以前想检查的。遗憾的是,我们仍然无法区分切片
对象与对象的区别。正如@PaulMcGuire所评论的,我可能不得不重新思考我的语法设计。为了添加到您的好例子中,m[slice\u obj]->“This\uu getitem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
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'