【问题标题】:How to iterate through every class declaration, descended from a particular base class?如何遍历从特定基类派生的每个类声明?
【发布时间】:2012-02-15 22:25:41
【问题描述】:

当我调用setup_all() 时,我在想,elixir\sqlalchemy 如何知道我在模型中声明的所有实体类?我在我的一个小项目中需要这种功能,但我不知道。我试图通过 elixir 的setup_all() 逐步跟踪,我发现它在“全局”列表中保存了所有实体类的集合(或者它是 dict?),但我无法捕捉到列表的时刻填充。有什么想法吗?

【问题讨论】:

    标签: python sqlalchemy python-elixir


    【解决方案1】:

    对于类定义,这更容易(无需导入)

    def find_subclasses(cls):
        results = []
        for sc in cls.__subclasses__():
            results.append(sc)
        return results
    

    我不确定你是想要这个还是对象。如果你想要对象:

    import gc
    
    def find_subclasses(cls):
        results = []
        for sc in cls.__subclasses__():
            for obj in gc.get_objects():
                if isinstance(obj, sc):
                   results.append(obj)
        return results
    

    【讨论】:

    • 是的,我想要定义,而不是实例。谢谢!短版规则。
    • 但是,应该提到 subclasses 仅适用于新样式类,并且它是可调用的,因此至少在 2.7.x 上应该是 cls.__subclasses__()
    • @AlexVhr 你真的不应该再使用旧式的类了。
    【解决方案2】:

    回答主要问题,完全不使用 SQLALchemy 或 elixir - 是的,这在 Python 中是可能的。

    标准库上的垃圾收集器 (gc) 模块有一个函数调用,允许检索对给定对象的所有引用,在解释器范围内。一个类总是在任何继承类的__mro__ 属性中被引用。

    因此,以下函数可以检索从给定类继承的所有类:

    import gc
    def find_subclasses(cls):
        all_refs = gc.get_referrers(cls)
        results = []
        for obj in all_refs:
            # __mro__ attributes are tuples
            # and if a tuple is found here, the given class is one of its members
            if (isinstance(obj, tuple) and
                # check if the found tuple is the __mro__ attribute of a class
                getattr(obj[0], "__mro__", None) is obj):
                results.append(obj[0])
        return results
    

    【讨论】:

      猜你喜欢
      • 2017-07-04
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-11
      • 1970-01-01
      • 2011-04-02
      • 2014-03-21
      相关资源
      最近更新 更多