Python 按嵌套子类的顺序查找类中的嵌套子类';重新定义

Python 按嵌套子类的顺序查找类中的嵌套子类';重新定义,python,class,oop,python-2.5,Python,Class,Oop,Python 2.5,想象一下这样的情况: class A: pass class B: x = 5 class D(A): pass class C(A): pass 我想要的是找到类B中属于A子类的所有类: >>> for cls in dir(B): if issubclass(cls, A): print(cls) <class '__main__.C'> <class '__mai

想象一下这样的情况:

class A:
    pass

class B:
    x = 5
    class D(A):
        pass
    class C(A):
        pass
我想要的是找到类
B
中属于
A
子类的所有类:

>>> for cls in dir(B):
    if issubclass(cls, A):
        print(cls)
<class '__main__.C'>
<class '__main__.D'>
他们可以写:

class MyHero(Hero):
    name = 'My Hero'
    description = 'My description'
    ...

    class MySpell1(Spell):
        name = ...

    class MySpell2(Spell):
        ...

显然,第二种方法看起来比第一种方法好得多,对于一个不太懂Python的人来说甚至更有用。

可能是这样的,可能会有所帮助:

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)
更新

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

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)

p.S.Python类也是对象

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

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)
更新

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

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)

p.S.Python类也是对象

元类文档包括如何让类记住其成员的定义顺序:

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')
您可以将其改编为您的案例,如下所示:

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)))
给出:

['D', 'C']
请注意,这将为您提供类的名称;如果您想要类本身,可以这样做:

print(list(filter(lambda x: isinstance(x, type), (getattr(B, x) for x in B.members))))

元类文档包括如何让类记住其成员的定义顺序的详细说明:

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')
您可以将其改编为您的案例,如下所示:

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)))
给出:

['D', 'C']
请注意,这将为您提供类的名称;如果您想要类本身,可以这样做:

print(list(filter(lambda x: isinstance(x, type), (getattr(B, x) for x in B.members))))

你为什么要这么做?如果顺序很重要,那么将它们存储在一个有序的容器中。为什么还要嵌套类呢?这在Python中没有任何意义。@jonrsharpe阅读了编辑,我试图解释:P如果您有任何想法,请随意给出更好的想法…@MarkusMeskanen您可以将用户配置与Python分离-定义他们可以使用的文本文件格式,然后将其解析为适当的Python对象。为什么要求用户学习Python?这也可以避免让那些在看到类属性时确实知道类属性的人感到恼火!你为什么要这么做?如果顺序很重要,那么将它们存储在一个有序的容器中。为什么还要嵌套类呢?这在Python中没有任何意义。@jonrsharpe阅读了编辑,我试图解释:P如果您有任何想法,请随意给出更好的想法…@MarkusMeskanen您可以将用户配置与Python分离-定义他们可以使用的文本文件格式,然后将其解析为适当的Python对象。为什么要求用户学习Python?这也可以避免让那些在看到类属性时确实知道类属性的人感到恼火!这并没有真正的帮助-
MyHero.\uuu dict\uuuu
是一个字典,因此没有保证的顺序这是您问题答案的一部分:字典中存储的所有类属性,正如您所说,字典是无序集合。因此,如果您想使用这样的方案,您应该向每个嵌套类添加一个顺序号。这并没有真正的帮助-
MyHero.\uuu dict\uuuu
是一个字典,因此没有保证的顺序这是您问题答案的一部分:字典中存储的所有类属性,正如您所说的字典是无序集合。因此,如果您想使用这样的方案,您应该向每个嵌套类添加一个订单号。这似乎很有希望,但我使用的是Python 2.5,而
\uuuu prepare\uuuuu
在那里不起作用:/@MarkusMeskanen建议在Python 3中对元类进行更改,并以此作为添加
\uu prepare\uu
的理由:“对于Python程序员来说,直接使用类成员的声明顺序来指定这样的顺序是很有用的。目前,必须使用其他机制明确指定此类排序”(我的重点)。因此,您所要求的在Python2.x中是不可能直接实现的。这似乎是有希望的,但我在Python2.5上,
\uuuuuu prepare\uuuuu
在那里不起作用:/@MarkusMeskanen建议对Python3中的元类进行更改,并以此作为添加
\uu prepare\uuu
的理由。”对于Python程序员来说,直接使用类成员的声明顺序指定这样的顺序是很有用的。目前,必须使用其他机制明确指定此类排序”(我的重点),因此,在Python2.x中无法直接实现您的要求。