什么是订购调用对象方法的最pythonic方式,没有

什么是订购调用对象方法的最pythonic方式,没有

问题描述:

当您给开发者一个“robs_numbers”对象时,开发人员可以按照他们想要的任何顺序调用各种过滤器, obj.filter1()。filter2()。filtern()..什么是订购调用对象方法的最pythonic方式,没有

但是,通常我筛选出的数字越早,过滤速度就越快。

我希望开发人员能够以他们想要的任何顺序调用filter()方法。 开发人员然后获取一个robs_numbers对象(或者可能是一个可迭代的..)。 但是我希望我的方法(过滤器)按照priority()给出的顺序实际运行。

从技术上讲,priority()应该采用pair filter:[args],以便我可以使用任何过滤器。那么优先级()将返回的优先级值

下面是一些示例代码,虽然你可能完全改变,如果它是更Python对象:

from random import randint 
data = [randint(0,100) for i in range(100)] 

class robs_numbers(): 
    def __init__(self,numbers,_min,_max): 
     self.numbers = iter(numbers) 
     self._min = _min #approx 
     self._max = _max #approx 

    def bigger(self,x): 
     print "priority = ", self.priority(x) 
     return robs_numbers([i for i in self.numbers if i>x],x,self._max) 

    def smaller(self,x): 
     print "priority = ", self.priority(x) 
     return robs_numbers([i for i in self.numbers if i<x],self._min,x) 

    def order(self,backwards=False): 
     print "priority = ", self.priority() 
     self.numbers = iter(sorted(self.numbers,reverse=backwards)) 
     return self 

    # ... 
    # More filter methods 
    # ... 

    def priority(self,x=None): 
     #works out the order methods should be called to increase efficiency 
     if x is None: 
      return 99999 
     else: 
      return abs(x-(self._max-self._min)/2) 

和例如两个有效的用途,但我想他们两个要快,现在只有一个是有效的:

def get(): 
    return robs_numbers(data,0,100) 

rf = get().bigger(80).smaller(90).order() #faster in this order 
print list(rf.numbers), rf._min, rf._max 

#priority = 30 
#priority = 80 
#priority = 99999 
#[81, 81, 82, 83, 85, 86, 87, 87, 89] 80 90 


rf = get().order().smaller(90).bigger(80) #slower in this order 
print list(rf.numbers), rf._min, rf._max 
#priority = 99999 
#priority = 40 
#priority = 35 
#[81, 81, 82, 83, 85, 86, 87, 87, 89] 80 90 

你必须创建某种懒洋洋地评估查询组,每当开发者调用list()或其他什么东西,需要你只执行所有的过滤器导出数据到另一个对象。 Django在他们的查询集中有一个很好的例子,which are lazy

所以,你可以写东西的

class RobsNumbers(object): 
    def __init__(self, numbers, min, max): 
     self._numbers = numbers 
     self._min = min 
     self._max = max 
     self._filters = [] 

    def bigger(self, x): 
     new_obj = RobsNumbers(self._numbers, x, self._max) 
     new_obj._filters = self._filters + [GreaterThanFilter(x)] 
     return new_obj 

    # Other filter methods simply add a filter to the _filters list of the object 

    def __iter__(self): 
     # Here is the complicated optimization logic to reorder and execute the filters 
     pass 

注意,大意是这个代码零过滤,直到开发者请求包含在RobsNumbers对象里面的数据,所以它是很懒惰。

+0

谢谢,这看起来相当简单。我现在只是仰望“懒惰”。即使他们在添加更多过滤器之前消费了itertools.islice(),它也可能仍然有效; p – 2012-03-02 06:11:57