代码之家  ›  专栏  ›  技术社区  ›  nicolas

在python中重定向对类成员的调用

  •  0
  • nicolas  · 技术社区  · 14 年前

    collections.defaultdict(lambda: 1)
    

    通过添加两种方法,分别称为“词汇”和“字数” 显然,无法将attr方法设置为builin类型,也无法从defaultdic继承,因此我决定编写一个类,并将对它的调用重定向到我想要扩展的类型。

    class BagOfWordDoc():
        def __init__(self):
            self.data = collections.defaultdict(lambda: 1)
            for method in dir(self.data):
                if hasattr(getattr(self.data, method),'__call__') and method not in ['__class__', '__self__']:
                    l = lambda *args: getattr(self.data, method)(*args)
                    setattr(self, method,l)
    
        def vocabulary(self):
            return self.data.keys()
    
        def wordcount(self):
            return reduce(operator.add, self.data.values(), 0) 
    

     doc = BagOfWordDoc()
     doc[123]   = 123          # yields TypeError: values() takes no arguments (1 given)
     doc.keys()                # yields TypeError: values() takes no arguments (1 given)
     doc.xxx()                 # yields TypeError: values() takes no arguments (1 given)
    

    因此,就好像每个lambda都映射到了“values”函数 “值”是属性列表的最后一个元素

    至于最初的问题,我现在正在考虑重写我自己的defaultdict。

    更新

    根据提出的建议,以下是工作实施:

    class BagOfWordDoc():
        def __init__(self):
            self.data = collections.defaultdict(lambda: 0)
    
        def __getattr__(self, *args):
            return self.data.__getattribute__(*args)
    
        def vocabulary(self):
            return self.data.keys()
    
        def wordcount(self):
            return reduce(operator.add, self.data.values(), 0) 
    
    2 回复  |  直到 14 年前
        1
  •  3
  •   Ignacio Vazquez-Abrams    14 年前

    可以从一个类复制到另一个类,而不是从一个实例复制到另一个实例,或者只需要 .__getattr__() 委托给封装的对象。

        2
  •  1
  •   mzz    14 年前

    #!/usr/bin/env python
    
    
    from collections import defaultdict
    import operator
    
    
    class DD(defaultdict):
    
       def vocabulary(self):
            return self.keys()
    
        def wordcount(self):
            return reduce(operator.add, self.data.itervalues(), 0)
    
    
    if __name__ == '__main__':
        dd = DD(int)
    
        dd[2] += 1
        print dd.vocabulary()