我想用Python编写一个函数,它以一个切片作为参数。理想情况下,用户可以按如下方式调用该函数:
foo(a:b:c)
不幸的是,Python不允许使用这种语法 - 使用 a:b:c
只允许进入 []
不是 ()
。
因此,我认为我的功能有三种可能性:
要求用户使用切片“构造函数”(其中 s_
表现得像 numpy提供的版本):
foo(slice(a, b, c))
foo(s_[a:b:c])
把我的函数的逻辑放入 __getitem__
方法:
foo[a:b:c]
放弃尝试切片并开始,停止和单独步骤:
foo(a, b, c)
有没有办法让原始语法工作?如果不是,首选哪种解决方法语法?或者还有另一种更好的选择吗?
不要让用户感到惊讶。
如果您使用切片语法与开发人员对切片语法的期望一致,那么同一个开发人员将期望使用方括号操作,即 __getitem__()
方法。
如果相反,返回的对象不是原始对象的切片,如果你坚持使用,人们会感到困惑 __getitem__()
解。使用函数调用 foo(a, b, c)
,根本不提切片,如果有意义,可选择指定默认值。
切片在表达为切片时更有意义。因此,另一种选择是更加面向对象:创建一个表示您的切片的临时对象,并将您的函数作为它的一种方法。
例如,如果你的功能是真的:
foo(bar, a:b:c)
要么
bar.foo(a:b:c)
然后你可以用以下代替:
bar[a:b:c].foo()
如果 bar[a:b:c]
已经有了不同的含义,然后拿出另一个名字 baz
并做:
bar.baz[a:b:c].foo()
如果没有真实的上下文,很难给出令人信服的例子,因为你试图用直观有意义的名字命名相关的东西,让你编写明确的代码,并且相对较短。
如果你真的只是在片上自己编写一个函数,那么:
您的函数修改切片,返回不同的切片:
bar[foo(a:b:c)]
如果是这种情况,无论您选择哪种有效语法,都会让人感到有些困惑。如果你的目标是广泛的Python程序员,你可能不想使用切片。
你的功能真的在运作 一片整数,所以你可以用一个临时对象来显式:
the_integers[a:b:c].foo()
指某东西的用途 [a:b:c]
就像你注意到的那样,是一种语法的东西。口译员提出了一个问题 syntax error
对于 (a:b:c)
马上,在您的代码有机会对值进行操作之前。没有重写解释器,没有办法绕过这种语法。
值得记住的是,口译员会进行翻译 foo[a:b:c]
至
foo.__getitem__(slice(a,b,c))
该 slice
对象本身并不是很复杂。它只有3个属性(start
,step
,stop
)和方法 indices
。就是这样 getitem
理解这些价值观的方法。
np.s_
和其他功能/类 np.lib.index_tricks
是如何的好例子 __getitem__
和 slice
可用于扩展(或简化)索引。例如,这些是等价的:
np.r_[3:4:10j]
np.linspace(3,4,10)
至于 foo(a,b,c)
语法,很常见 np.arange()
使用它。同样如此 range
和 xrange
。因此,您和您的用户应该非常熟悉它。
因为替代品最终都会给你提供 start/step/stop
三个值,它们在功能上是等效的(速度)。因此,选择取决于用户偏好和熟悉程度。
虽然你的功能不能采取 a:b:c
直接表示法,它可以编写来处理各种输入 - 一个切片,3个位置参数,一个元组,一个切片元组(从 s_
)或关键字参数。并遵循基本 numpy
索引你可以区分元组和列表。