【问题标题】:Set with expiration not working inside running Python script设置过期在运行的 Python 脚本中不起作用
【发布时间】:2013-10-31 04:17:17
【问题描述】:

我有一个名为 DecayingSet 的类,它是一个过期的双端队列

class DecayingSet:
    def __init__(self, timeout): # timeout in seconds
        from collections import deque
        self.timeout = timeout
        self.d = deque()
        self.present = set()

    def add(self, thing):
       # Return True if `thing` not already in set,
       # else return False.
        result = thing not in self.present
        if result:
          self.present.add(thing)
          self.d.append((time(), thing))
        self.clean()
        return result

    def clean(self):
       # forget stuff added >= `timeout` seconds ago
       now = time()
       d = self.d
       while d and now - d[0][0] >= self.timeout:
            _, thing = d.popleft()
            self.present.remove(thing)

我正在尝试在连接到流式 API 的运行脚本中使用它。 流 api 正在返回我试图放在双端队列中的 url,以限制它们进入程序的下一步。

    class CustomStreamListener(tweepy.StreamListener):
         def on_status(self, status, include_entities=True):
             longUrl = status.entities['urls'][0]['expanded_url']

             limit = DecayingSet(86400)
             l = limit.add(longUrl)
             print l
             if l == False:
              pass
             else:
              r = requests.get("http://api.some.url/show?url=%s"% longUrl)

当我在解释器中使用这个类时,一切都很好。 但是当脚本运行时,我重复发送相同的 url,l 每次返回 True 表示该 url 不在集合内,什么时候应该在。什么给了?

【问题讨论】:

  • 我认为缩进搞砸了,但它看起来每次调用on_status() 时,您都在创建一个全新的limit 对象。那么当然它总是会返回True:你总是会从一个空的limit开始。
  • 这是实际代码吗?上面有一个奇怪的缩进,我认为 Python 会窒息。
  • 是的,我在 qs 中的缩进是关闭的,它在代码中很好。是的!!我刚刚在解释器中看到 var 分配是罪魁祸首。我将如何使用相同的 obj?
  • 例如,您可以在模块级别创建limit 对象。如果没有 all 您的代码可供查看,我无法更具体。但这应该很容易;-)
  • 一如既往,这是我错过的简单事情。

标签: python process queue set


【解决方案1】:

复制我的评论 ;-) 我认为缩进搞砸了,但看起来你每次调用 on_status() 时都在创建一个全新的 limit 对象。那么当然它总是会返回True:你总是会从一个空的limit开始。

不管怎样,改变这个:

     l = limit.add(longUrl)
     print l
     if l == False:
        pass
     else:
        r = requests.get("http://api.some.url/show?url=%s"% longUrl)

到这里:

     if limit.add(longUrl):
        r = requests.get("http://api.some.url/show?url=%s"% longUrl)

更容易理解。 通常当您将某些内容与文字 TrueFalse 进行比较时,可以使代码更具可读性。

编辑

我刚刚在解释器中看到 var 赋值是罪魁祸首。 我将如何使用相同的 obj?

例如,您可以在模块级别创建limit 对象。剪切和粘贴 ;-)

【讨论】:

  • 但是比较是从哪里来的,代码怎么知道当真或假返回时该怎么做呢?这是默认行为
  • 嘿 - 阅读 if 声明的文档。 if <expression>: <block> 执行 <block> 当且仅当 <expression> 评估为“真实”值。没有什么比True更多真实,也没有什么比False 更真实;-) 比较与它无关!比较只是编写“真实”表达式的一种方式。
  • 谢谢! @蒂姆-彼得斯。 True 是默认值,它是 TRUTH!如果正在寻找真相,那就是这样。在别处创建限制 obj。我将 limit = DecayingSet(86400) 移到了类/函数之外!现在它像宣传的那样工作
  • 把它放在答案中并且不接受它......“在其他地方创建限制对象”
  • 我在我的设计中发现了一个缺陷。如果我重新启动脚本,则会创建一个新的 obj 实例,因此允许重复输入。无论如何,要使设置在脚本重置时保持不变。 Memcache 可能是要走的路,或者有办法将集合保存到磁盘,然后即使在重新启动期间也继续检查该对象。要研究泡菜、搁置和推...我在正确的轨道上吗?
猜你喜欢
  • 2021-03-07
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 2018-02-15
  • 2019-05-11
  • 1970-01-01
相关资源
最近更新 更多