从类对象继承属性的类对象的python dict

时间:2013-09-03 02:33:17

标签: python subclass multiple-inheritance metaclass

如何创建一个字典类'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 的组合可以满足我的需求,但我正在探索如何通过较少的硬编码来实现这一目标。

我认为这是一个常见的设计问题,你想要动态生成一个迭代,它的行为与它所包含的对象有些相似。

2 个答案:

答案 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()方法?

我建议用更具体的内容重新构思或重新提出这个问题。首先,字典中的对象代表什么?更重要的是字典代表什么?