在类构造函数中定义 __getitem__()

问题描述 投票:0回答:1

Python 允许直接将函数定义分配给类成员,例如,

class A:
  def __init__(self):
    self.test = lambda x: print(x)

a = A()
a.test(10) # prints 10

但是对于

__getitem__(self, idx)
来说,事情就没那么简单了。假设您有两种可能的
__getitem__
实现,具体取决于标志变量。人们可以简单地写,

class A:
  def __init__(self, N, flag):
    self.values = list(range(N))
    self.flag = flag
  def __getitem__(self, idx).
    if flag: 
      return self.values[idx]
    else:
      return self.values[idx] * self.N    # toy example

a = A(10, True)
a[5] # returns 6

但是,如果我想避免在

__getitem__
中执行 if-else 逻辑,例如在面向数据的应用程序中,我希望能够在构造函数中进行该测试。比如,

class A:
  def __init__(self, N, flag):
    self.values = list(range(N))
    self.flag = flag
    self.N = N
    if flag: 
      self.__getitem__ = lambda self, idx: return self.values[idx]
    else:
      self.__getitem__ = lambda self, idx: return self.values[idx] * self.N

a = A(10, False)
a[5] # should return 12, instead yields NotImplementedError

然而,最后一个片段会产生一个 NotImplementedError。有没有办法做到这一点,或者 python 是否已经像上面那样优化了 if-else 块?

python constructor
1个回答
0
投票

如果您只想在构造函数中编写条件,那么重新排列 lambda 函数也许可以帮助您。

例如,

class A:
    def __init__(self, N, flag):
        self.values = list(range(N))
        self.flag = flag
        if flag:
            self.cond = lambda idx:  self.values[idx]
        else:
            self.cond = lambda idx : self.values[idx] * 2

    def __getitem__(self, item):
        return self.cond(item)

a = A(10, False)
print(a[5]) # returns 5 x 2 = 10
© www.soinside.com 2019 - 2024. All rights reserved.