【问题标题】:Using keyword arguments in __getitem__ method in Python在 Python 的 __getitem__ 方法中使用关键字参数
【发布时间】:2015-08-10 09:58:42
【问题描述】:

我想定义一个类 Foo,它的对象可以像 foo[1, a=2] 这样使用。

我试图通过装饰__getitem__ 方法来实现这一点 Foo但没有成功。下面是示例代码。

def decorator(func):
    def func_(*args, **kewargs):
        if 'a' in kewargs:
            args = list(args) + [kewargs['a']]
            return func(*args)
        else:
            return func(*args)
    return func_

class Foo(object):
    @decorator
    def __getitem__(self, *items):
        return items
foo = Foo()

>>> foo.__getitem__(2, a=10)
(2, 10)
>>> foo[2, a=10]
SyntaxError: invalid syntax

所以foo[...] 不等于foo.__getitem__(...),有些东西 幕后是为前者做的。我的问题是究竟是什么以及如何 我可以让foo[2, a=10] 工作吗?

【问题讨论】:

  • 你想让foo[2, a=10]做什么,到底是什么?我们可以告诉您,该语法永远不会起作用,但在不知道目标的情况下,我们无法提出任何建议。请注意,__getitem__ 总是(我认为...)有两个参数:self,以及调用时使用的方括号的内容。
  • 那不行,订阅中不能有关键字参数
  • @jonrsharpe:我想通过允许关键字 args 使调用 foo.[...] 更加方便。
  • ...我上面的评论代表

标签: python metaprogramming


【解决方案1】:

Python 允许创建隐式元组(不带括号):

In [2]: tup = 1, 2, 3

In [3]: tup
Out[3]: (1, 2, 3)

在方括号内也是一样的:

In [4]: d = {(1, 2, 3): 4}

In [5]: d[1, 2, 3]
Out[5]: 4

(2, a=10) 不是有效的元组文字:

In [6]: (2, a=10)
  File "<ipython-input-1-7dc03602f595>", line 1
    (2, a=10)
         ^
SyntaxError: invalid syntax

简单地说,你不能让foo[2, a=10] 工作,因为无论你如何调整你的__getitem__ 实现,这都是一个语法错误。

我可能会定义一个普通的方法,例如get 并像 Foo.get(2, a=10) 一样使用它。

【讨论】:

  • 我想在 '[]' 将它的参数转换为元组之前拦截它,这是我试图用装饰器做的,但没有成功。
  • @Tima 正如我所说,装饰器(或任何东西,真的)不会帮助您避免语法错误。你的代码甚至没有机会被执行。
【解决方案2】:

这是针对 python 3.6 提出的

目前使用关键字参数进行索引是一个语法错误。

但是,PEP472 (https://www.python.org/dev/peps/pep-0472/) 建议在 python 语法中添加此内容。

解决方法

PEP 还显示当前有效的解决方法:

foo[2, "a":10]foo[2, {"a":10}]

【讨论】:

  • 第一个解决方法foo[2, "a":10] 被 PEP 认为是深奥的。它使用切片对象而不是字典(例如在这种情况下询问"a"10 之间的范围)。将 slice 对象解析为 dict 可能会非常晦涩,并且您可能会失去对 slice 对象的其他用法的支持。 foo[2, {"a": 10}] 可能是最接近 OP 想要的选项。
猜你喜欢
  • 2012-10-30
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
  • 2013-08-16
  • 2011-02-14
  • 1970-01-01
相关资源
最近更新 更多