【问题标题】:Have exception hit two except blocks in python有异常命中两个除了python中的块
【发布时间】:2015-07-26 13:42:26
【问题描述】:

这是我想在代码中做的一个例子:

class MyClass(object):

    @classmethod
    def test_func(cls, x):

        try:
            return cls.cache[x]

        except AttributeError:
            cls.cache = {}

        except (AttributeError, KeyError):
            cls.cache[x] = "CACHE STORE"
            return cls.cache[x]

这里的想法是我的班级将根据输入 x 缓存一些结果。但是,我不想在需要之前开始创建缓存。所以我第一次将任何x 传递给它时,我希望它创建缓存,并用一些东西填充它。有没有办法让它同时击中except 块?现在它目前只打第一个

【问题讨论】:

  • 听起来你想要一个singleton...
  • 创建一个空的字典会给你的类的创建增加微不足道的开销。只需将cache = {} 作为类属性即可。
  • 我认为您可以改编我之前写的答案:stackoverflow.com/a/30235268/3001761

标签: python exception try-catch


【解决方案1】:

正如我在评论中所建议的,只需在创建类时将cache 设为类属性。除非你有一个真的很好的理由不这样做,否则你只是在不必要地使你的实现复杂化

class MyClass(object):

    cache = {}

    @classmethod
    def test_func(cls, x):
        try:
            return cls.cache[x]
        except KeyError:
            cls.cache[x] = "CACHE STORE"
            return cls.cache[x]

一旦你这样做了,你甚至不需要try 声明;你可以使用setdefault

@classmethod
def test_func(cls, x):
    return cls.cache.setdefault(x, "CACHE STORE")

【讨论】:

    【解决方案2】:

    我会在这里进行递归:

    class MyClass(object):
    
        @classmethod
        def test_func(cls, x):
    
            try:
                return cls.cache[x]
    
            except AttributeError:
                cls.cache = {}
                return cls.test_func(x)  # Add this line
    
            except KeyError:
                cls.cache[x] = "CACHE STORE"
                return cls.cache[x]
    

    【讨论】:

      【解决方案3】:

      使用defaultdict

      from collections import defaultdict as dd
      
      class MyClass(object):
          cache = dd(lambda: "CACHE STORE")
          @classmethod
          def test_func(cls, x):
              return cls.cache[x]
      

      来自文档:

      返回一个新的类字典对象。 defaultdict 是内置 dict 类的子类。它覆盖了一种方法并添加了一个可写实例变量。其余功能与 dict 类相同,此处不作说明。

      第一个参数提供 default_factory 属性的初始值;它默认为无。所有剩余的参数都被视为与传递给 dict 构造函数一样,包括关键字参数。

      我同意其他人的观点,即从一开始就将其添加为类属性不会有任何损失。但是如果你真的坚持在需要之前不创建缓存,你可以这样做:

      from collections import defaultdict as dd
      
      class MyClass(object):
          @classmethod
          def test_func(cls, x):
              try:
                  return cls.cache[x]
              except AttributeError:
                  cls.cache = dd(lambda: "CACHE STORE")
                  return cls.test_func(x)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-20
        • 1970-01-01
        • 2011-07-30
        • 2017-05-13
        • 2013-10-29
        • 2015-02-08
        • 1970-01-01
        相关资源
        最近更新 更多