在构造类obj之后执行代码

2024-10-01 11:33:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望通过将每个子类注册到父类保存的列表中,列出给定类的所有子类,例如:

class Monster(object):
    monsters = list()
class Lochness(Monster):
    Monster.monsters.append(Lochness)
class Yeti(Monster):
    Monster.monsters.append(Yeti)

这显然行不通,因为当我想将类添加到列表中时,这些类还没有创建出来。而且,如果是自动完成的话会更好(比如uu子类)

我知道uu子类有这个功能,但是我想知道(为了我自己的启发)您如何自己实现它。在

看起来你想创建一些元类的子类,创建所有的东西来注册怪物?或者这是完全不合理的吗


Tags: 功能列表object子类listclassuuappend
3条回答

为了保留代码,请在类的定义之外添加类:

class Monster(object):
    monsters = list()

class Lochness(Monster):
    pass
Monster.monsters.append(Lochness)

class Yeti(Monster):
    pass 
Monster.monsters.append(Yeti)

但是,如前所述:如果这是一个共同的特性,那么就创建一个元类

除了本例中使用type.__subclasses__()的明显解决方案外,您还可以使用decorator来解决类似的问题:

class Monster(object):
    monsters = list()

def isMonster(cls):
    Monster.monsters.append(cls)
    return cls

@isMonster
class Lochness(Monster):
    pass

@isMonster
class Yeti(Monster):
    pass

print(Monster.monsters) # [<class '__main__.Lochness'>, <class '__main__.Yeti'>]

类已经注册了定义的子类;调用^{} method获取列表:

>>> class Monster(object):
...     pass
... 
>>> class Lochness(Monster):
...     pass
... 
>>> class Yeti(Monster):
...     pass
... 
>>> Monster.__subclasses__()
[<class '__main__.Lochness'>, <class '__main__.Yeti'>]

.__subclasses__()返回当前仍在活动的子类的列表。当你不再调用cd4{d>中的所有引用时,{cd4}将不再调用.__subclasses__()是一个CPython implementation detail,但该方法存在于所有支持新样式类的Python版本中(2.2及更高版本,一直到3.x)。在

否则,钩住类创建的规范方法是定义一个metaclass

^{pr2}$

演示:

^{3}$

或者您可以使用class decorator

def registered_monster(cls):
    Monster.monsters.append(cls)
    return cls

class Monster(object):
    monsters = []

@registered_monster
class Lochness(Monster):
    pass

@registered_monster
class Yeti(Monster):
    pass

演示:

>>> class Monster(object):
...     monsters = []
... 
>>> @registered_monster
... class Lochness(Monster):
...     pass
... 
>>> @registered_monster
... class Yeti(Monster):
...     pass
... 
>>> Monster.monsters
[<class '__main__.Lochness'>, <class '__main__.Yeti'>]

不同之处在于,注册怪物的职责是:使用基MonstersMeta类型,还是显式修饰符。在

不管怎样,元类或类装饰器注册一个永久引用。如果您真的非常想模拟.__subclasses__()行为,可以使用^{} module。在

相关问题 更多 >