Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 区分作为一维索引传递给_getitem_uuu的元组与多维索引集?_Python_Indexing_Tuples_Magic Methods - Fatal编程技术网

Python 区分作为一维索引传递给_getitem_uuu的元组与多维索引集?

Python 区分作为一维索引传递给_getitem_uuu的元组与多维索引集?,python,indexing,tuples,magic-methods,Python,Indexing,Tuples,Magic Methods,考虑一个类来镜像传递给\uu getitem\uu的参数: class RequestedItems(object): def __getitem__(self, args): return args 一些示例(其中r=RequestedItems()): 我如何区分用户仅传递一个试图获取的项目时的情况,以及该项目本身是一个元组,与用户试图获取多维项目时的情况: In [83]: r[1, 2, 3] Out[83]: (1, 2, 3) In [84]: r[(1,

考虑一个类来镜像传递给
\uu getitem\uu
的参数:

class RequestedItems(object):
    def __getitem__(self, args):
        return args
一些示例(其中
r=RequestedItems()
):

我如何区分用户仅传递一个试图获取的项目时的情况,以及该项目本身是一个
元组
,与用户试图获取多维项目时的情况:

In [83]: r[1, 2, 3]
Out[83]: (1, 2, 3)

In [84]: r[(1, 2, 3)]
Out[84]: (1, 2, 3)
示例

作为一个可能需要的例子,考虑编写一个装饰器,它将使用任何传递给ygGeTimeTys的函数作为其他函数的参数:

def target_getitem(function_name):
    def decorator(klass):
        def __getitem__(self, args):
            args = args if isinstance(args, tuple) else (args,) # For 1-D indexing
            return getattr(self, function_name)(*args)
        klass.__getitem__ = __getitem__
        return klass
    return decorator
然后我们可以这样做:

@target_getitem('sum')
class Foo(object):
    def sum(self, *args):
        import operator
        return reduce(lambda x,y: operator.add(x,y), args)
那么这就行了:

f = Foo()
f[1, 2, 3] # <-- prints 6
f[1] #<-- prints 1
f[(1, 2, 3), (4, 5, 6)] # <-- prints (1, 2, 3, 4, 5, 6)
f=Foo()

f[1,2,3]#注意,如果用户知道这个问题,用户可以使用尾随逗号调用
f[(1,2,3),]
,强制将元组视为多维切片的第一维度。但是,这需要用户首先知道这一点,然后在其他单值get请求(例如
f['foo']
)不需要相同的约定时放置尾随逗号(这是非常有趣的,因为
'foo'
的行为应该像一个字符元组,但是
\uuuu getitem\uuuuuuu
并不假设您想要
('f','o','o')
。难道没有办法区分这些情况吗。信息是单个元组还是“多个参数”传递的已在解析器中丢失。
subscription
的语法不接受多个参数,而是接受一个
expression\u list
。赋值也使用该语法,因此也无法区分
a=1,2
a=(1,2)
。在
a=1,2
vs
a=(1,2)
的情况下,这是有意义的。在有效的Python中,对
a=1,2
没有任何解释会允许
a
(1,2)不同
。但是在我上面用
\uuu getitem\uuuu>给出的例子中,在解析器中称之为bug几乎就足够了,因为有多种有效的方法来解释
f[(1,2,3)]
的含义。值得注意的是,因为
f['foo']
的解析方式与
f[('f','o','o')的解析方式不同
那么,不管解决方案是什么,Python当前的行为似乎无法辩护,因为
tuple
s的字符和
int
s的
tuple
s之间不一致。FWIW我同意这是一个解析器(或者可能是语言定义)错误。调用类似
func(1,2,3)的函数
应该与使用
func((1,2,3))调用它有所区别
而不需要在后者的末尾添加逗号(这是唯一想到的解决方法).@prpl.mnky.dshwshr我并不是试图通过解释当前行为在解析器中的实现方式来为其辩护,而是试图解释为什么我认为在实现
\uu getitem\uuuuuuu()时,目前无法区分这些情况
.IMHO,如果今天设计的话,我会投票支持下标操作符像函数调用一样解析参数,并将这些参数作为单个参数传递给
\uuuu getitem\uuuu()
。也就是说,foo[1,2]将等同于foo.\uu getitem\uuuuu(1,2)。但遗憾的是,事实并非如此。
f = Foo()
f[1, 2, 3] # <-- prints 6
f[1] #<-- prints 1
f[(1, 2, 3), (4, 5, 6)] # <-- prints (1, 2, 3, 4, 5, 6)
f[(1, 2, 3)] # <-- prints 6, but should print '(1, 2, 3)'