修改:
这个问题已被标记为重复,但我认为不是。实现建议的答案,即使用Mapping abc,没有我想要的行为:
from collections import Mapping
class data(Mapping):
def __init__(self,params):
self.params = params
def __getitem__(self,k):
print "getting",k
return self.params[k]
def __len__(self):
return len(self.params)
def __iter__(self):
return ( k for k in self.params.keys() )
def func(*args,**kwargs):
print "In func"
return None
ps = data({"p1":1.,"p2":2.})
print "\ncalling...."
func(ps)
print "\ncalling...."
func(**ps)
输出:
calling....
In func
calling....
in __getitem__ p2
in __getitem__ p1
In func
正如问题所述,这不是我想要的。
评论中给出的另一个解决方案是修改导致问题的例程。这肯定会奏效,但我正在寻找一个快速(懒惰?)修复!
问题:
除了通过**
之外,如何为类实现__getitem__
运算符?例如,我希望能够做到这一点::
def func(**kwargs):
<do some clever stuff>
x = some_generic_class():
func( **x )
没有对some_generic_class.__getitem__()
的隐式调用。在我的应用程序中,我已经实现了__getitem__
一些数据记录,当上面引用类时我不想执行它。
如果无法重载**
运算符,是否可以检测何时由于类传递给函数而调用__getitem__
,而不是显式?
背景
我正在研究一个物理模型,该模型是根据运行时根据用户输入选择的一组包构建的。模型的灵活结构意味着我很少知道所需的参数,因此我在模型之间传递dict
个参数名称和值。为了使这个用户更友好,我现在正在尝试开发一个类paramlist
,它使用一组例程执行一些一致性检查,设置默认值等来重载dict
功能。这个想法是我传递paramlist
的实例而不是dict。其中一个更重要的目标是记录物理包中哪些paramlist
成员被引用,哪些没有。下面是一个剥离版本,旨在维护第二个dict
,记录是否已引用参数::
class paramlist(object):
def __init__( self, params ):
self.params = copy(params)
self.used = { k:False for k in self.params }
def __getitem__(self, k):
try:
v = self.params[k]
except KeyError:
raise KeyError("Parameter {} not in parameter list".format(k))
else:
self.used[k] = True
return v
def __setitem__(self,k,v):
self.params[k] = v
self.used[k] = False
哪个没有我想要的行为:
ps = paramlist( {"p1":1.} )
def donothing( *args, **kwargs ):
return None
donothing(ps)
print paramlist.used["p1"]
donothing(**ps)
print paramlist.used["p1"]
输出:
False
True
我希望use
dict在两种情况下都保持False,这样我就可以告诉用户他们的一个参数没有被使用(暗示他们搞砸了,而是使用了默认值) 。我认为**
案例会对__getitem__
中的每个条目调用paramlist
。