gpt4 book ai didi

python - 构造类对象后执行代码

转载 作者:太空宇宙 更新时间:2023-11-03 12:21:28 24 4
gpt4 key购买 nike

我希望通过让每个子类在父类持有的列表中注册自己来制作给定类的所有子类的列表,即像这样:

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

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

我知道 __subclass__ 具有此功能,但我想知道(为了我自己的启发)您将如何自己实现它。

您似乎想要创建元类的某种子类,该元类正在创建所有内容以向 Monster 注册它?或者是完全偏离基地

最佳答案

已经注册定义了哪些子类;调用class.__subclasses__() method获取列表:

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

.__subclasses__() 返回当前仍然存在 子类的列表。如果您清除所有对 Yeti 的引用(模块中的 del Yeti,删除所有实例、子类、导入等),那么它将不再列出你调用 .__subclasses__()。请注意,本质上,.__subclasses__() 是一个 CPython implementation detail ,但该方法存在于所有支持新型类的 Python 版本中(2.2 及更高版本,一直到 3.x)。

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

class MonstersMeta(type):
def __new__(metaclass, name, bases, namespace):
cls = super(MonstersMeta, metaclass).__new__(metaclass, name, bases, namespace)
if issubclass(cls, Monster) and not cls is Monster:
Monster.monsters.append(cls)
return cls

class Monster(object):
__metaclass__ = MonstersMeta
monsters = []

class Lochness(Monster):
pass

class Yeti(Monster):
pass

演示:

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

或者您可以使用 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 类型,或使用显式装饰器。

无论哪种方式,元类或类装饰器都会注册一个永久引用。您可以使用 weakref module如果您真的非常想模仿 .__subclasses__() 行为。

关于python - 构造类对象后执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17784398/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com