想象一下这样的案例:
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 B
定义中的定义来获取它们,所以不要在D之前打印C,而是需要在C之前得到D. dir()
显然不起作用,因为它返回按字母顺序排序的列表。
如果有的话,我的其他选择是什么?
修改 我想要这个的原因是为了帮助#34;玩家&#34;尽可能轻松地制作自己的英雄/冠军(视频游戏)。所以不必写:
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__(...):
...
他们可以写:
class MyHero(Hero):
name = 'My Hero'
description = 'My description'
...
class MySpell1(Spell):
name = ...
class MySpell2(Spell):
...
显然,第二个看起来比第一个好得多,对于一个对Python知之甚少的人来说更是如此。
答案 0 :(得分:3)
元类文档包含一个很好的example如何使类记住其成员的定义顺序:
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))))
答案 1 :(得分:1)
可能会有所帮助:
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类也是对象