如何创建一个字典类'D'来存储某些类'A'的实例并继承'A'方法的包装版本?
例如,假设a = A()和a.first()是对'a'执行某些操作并返回某个对象的函数。然后我想d = D({'k0':a0,'k1':a1})有一个属性d.first()返回{'k0':a0.first(),'k1':a1.first ()}并更改a0和a1中的基础数据,就像调用first()。
一样另外,我想只暴露dict类中不存在的方法(可能是属性)(没有st脚)我想要动态动态(没有方法的硬编码A,我已经知道如何手动输入所有方法)。也许只考虑处理不以'_'开头的方法,如果这样做更容易。
此外,我希望'D'根据返回类型(后处理,包装任何内容)对来自调用的输出进行一些处理。
看起来这可能是一个坏主意,但我只想了解有哪些方法。从我到目前为止的阅读,似乎我可以使用多重继承并编写我自己的__new__
函数或使用元类别做其他事情。但是,除非你是一个大师,否则你通常不应该与__new__
混在一起,所以这让我犹豫不决。这样做有一些装饰技巧吗?我想我也可以使用inspect模块来遍历“A”类,但这感觉就像黑客一样。
更新:作为一个非常具体的例子。想象一下,我有一个pandas.DataFrames的字典,我希望集合尽可能地出现和行为,就像单个DataFrame一样,甚至可以在iPython中使用方法完成选项卡(我没有使用pandas.Panel)。为简单起见,只考虑只读行为(索引和选择),d.ix [0:10]和d.mean()之类的东西应该返回从将函数应用到字典中的所有帧的同时d ['k0 ']应返回与键'k0'对应的字典中的值。硬编码和 getattr 的组合可以满足我的需求,但我正在探索如何通过较少的硬编码来实现这一目标。
我认为这是一个常见的设计问题,你想要动态生成一个迭代,它的行为与它所包含的对象有些相似。
答案 0 :(得分:1)
其中每一项都在有限的测试中工作:
#! /usr/bin/python3
class D(dict):
def __getattr__(self, name):
return lambda *args, **kw: {
k:getattr(v,name)(*args, **kw) for k,v in self.items() }
class D(dict):
def __getattr__(self, name):
def proxy(*args, **kw):
d2 = {k:getattr(v,name)(*args, **kw) for k,v in self.items()}
# Post-process if required
return d2
return proxy
d = D()
d['k1']='a1'
d['k2']='a2'
d['k3']='33'
print(d.capitalize()) # No-arg form passed to str, not dict
print(d.replace('a', 'Hello')) # Arguments
print(d.get('k1')) # .get() satisified by dict, not str
答案 1 :(得分:0)
这是一个奇怪的问题,但它在很大程度上取决于'D'在结构上是什么。 如果D只是一个数据结构,那么将字典打包带有对象,子脚并调用函数是完全有效的:
class A(object):
def __init__(self,x):
self.x = x
def first(self):
return self.x
a = A(7)
b = A(3)
d = {'X':a,'Y':b}
print d['X'].first()
除此之外,如果你想要所有的“第一”,那么你可以做这样的事情:
firsts = {}
for i,j in d:
firsts[i]=j.first()
然而,看起来您的挑战有点复杂,加上不安全:如果词典中的一个客观有keys()
方法怎么办?哪个优先,如果是词典,我如何访问内容的keys()
方法?
我建议用更具体的内容重新构思或重新提出这个问题。首先,字典中的对象代表什么?更重要的是字典代表什么?