首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按照定义的顺序查找类中的嵌套子类

按照定义的顺序查找类中的嵌套子类
EN

Stack Overflow用户
提问于 2014-04-24 14:02:19
回答 2查看 54关注 0票数 0

想象一下这样的情况:

代码语言:javascript
复制
class A:
    pass

class B:
    x = 5
    class D(A):
        pass
    class C(A):
        pass

我想要的是找到B类中属于A子类的所有类。

代码语言:javascript
复制
>>> for cls in dir(B):
    if issubclass(cls, A):
        print(cls)
<class '__main__.C'>
<class '__main__.D'>

它按预期工作,但问题是:我需要按照它们在class B定义中的不同顺序得到它们,所以我需要在D之前打印C,而是在C之前得到D。使用dir()显然不起作用,因为它返回按字母顺序排序的列表。我还有什么选择,如果有的话?

编辑:我之所以想这样做是为了帮助“玩家”尽可能容易地让自己的英雄/冠军(对于电子游戏)变得更容易。所以不必写:

代码语言:javascript
复制
class MyHero(Hero):
     def __init__(self, name='My Hero', description='My description', ...):
          super().__init__(name, description, ...)
          self.spells = [MySpell1(), MySpell2(), MySpell3()]

class MySpell1(Spell):
     def __init__(...):
          ...

他们可以写:

代码语言:javascript
复制
class MyHero(Hero):
    name = 'My Hero'
    description = 'My description'
    ...

    class MySpell1(Spell):
        name = ...

    class MySpell2(Spell):
        ...

显然,第二个比第一个要好得多,对一个不太懂Python的人来说更是如此。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-24 15:10:30

元类文档包括一个很好的示例,说明如何获得一个类来记住它的成员是在什么顺序中定义的:

代码语言:javascript
复制
class OrderedClass(type):

     @classmethod
     def __prepare__(metacls, name, bases, **kwds):
        return collections.OrderedDict()

     def __new__(cls, name, bases, namespace, **kwds):
        result = type.__new__(cls, name, bases, dict(namespace))
        result.members = tuple(namespace)
        return result

class A(metaclass=OrderedClass):
    def one(self): pass
    def two(self): pass
    def three(self): pass
    def four(self): pass 


>>> A.members
('__module__', 'one', 'two', 'three', 'four')

你可以像这样适应你的情况:

代码语言:javascript
复制
class A:
    pass

class B(metaclass=OrderedClass):
    x = 5
    class D(A):
        pass
    class C(A):
        pass

print(filter(lambda x: isinstance(getattr(B, x), type), b.members)))

给予:

代码语言:javascript
复制
['D', 'C']

请注意,这给出了类的名称;如果需要类本身,则可以这样做:

代码语言:javascript
复制
print(list(filter(lambda x: isinstance(x, type), (getattr(B, x) for x in B.members))))
票数 3
EN

Stack Overflow用户

发布于 2014-04-24 14:48:40

像这样的东西可能会有帮助:

代码语言:javascript
复制
import inspect

class Spell(object):
    name = "Abstract spell"

class MyHero(object):
    name = "BATMAN"
    description = "the bat man"

    class MySpell1(Spell):
        name = "Fly"

    class MySpell2(Spell):
        name = "Sleep"


for k, v in MyHero.__dict__.iteritems():
    if inspect.isclass(v) and issubclass(v, Spell):
        print "%s cast the spell %s" % (MyHero.name, v.name)

更新

另一种按类属性迭代的方法是:

代码语言:javascript
复制
for attr_name in dir(MyHero):
    attr = getattr(MyHero, attr_name)
    if inspect.isclass(attr) and issubclass(attr, Spell):
        print "%s cast the spell %s" % (MyHero.name, attr.name)

Python类也是对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23271192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档