有没有一种方法可以快速创建子类?

2024-04-28 07:26:24 发布

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

我正在创建一个游戏,其中我有一个有点复杂的方法来创建实体。

加载一个级别时,加载代码读取一堆包含所有不同可能单元属性的YAML文件。使用YAML文件,它创建一个所谓的EntityResource对象。这个EntityResource对象在生成新单元时充当权威信息源。目标有两个:

  1. 通过对YAML文件的输出执行哈希检查来阻止作弊
  2. 通过让所有单元信息都来自一个权威的源来帮助调试。

然后,这些EntityResource对象被馈送到EntityFactory对象中,以生成特定类型的单元。

我的问题如下。是否可以根据正在读取的YAML文件的内容动态创建EntityResource的子cases?

另外,我希望这些YAML文件派生的子类中的每一个都被分配一个单例元类。有什么需要注意的吗?


Tags: 文件对象方法代码实体信息游戏yaml
3条回答

我不确定这是否是您想要的,但是您可以使用^{}动态创建子类:

SubClass = type('SubClass', (EntityResource,), {})

编辑:要理解type是如何工作的,您只需要转换如何编写类并将其转换为type调用。例如,如果你想写一些东西,比如:

class SubClass(EntityResource):
    A=1
    B=2

然后,这将被翻译为:

 SubClass = type('SubClass', (EntityResource,), {'A': 1, 'B': 2})

其中:

  • 第一个参数只是类名
  • 第二个参数是父类列表
  • 第三个参数是字典初始化类对象。这不仅包括类属性,还包括方法。

当我听到“动态创建子类”时,我理解“动态创建行为不同的对象”,这实际上是一个配置的问题。

有没有什么东西你仅仅通过读取一些数据并创建一个对象来决定它将如何根据它所读取的内容来运行而得不到的呢?

这里有一个比喻:我是一个手巧的人——我可以把你扔给我的任何宜家商品放在一起。但我并不是每次都是一个不同的人,我只是同一个手巧的人,阅读不同的图表,寻找不同种类的螺丝和木片。这就是我的理由,子类化不是这里的自然解决方案。

可以动态创建子类。这并不意味着你应该。无论如何,我会提供一个机制。

每个类中的bases属性告诉您继承链:

class Animal(object):
    pass

class Dog(Animal):
    pass

print Animal.__bases__
print Dog.__bases__
# prints:
#(<type 'object'>,)
#(<class '__main__.Animal'>,)

因此,__bases__是一个具有“继承基”的元组。您可以替换这个元组(不能“附加到它”或“从它弹出”,因为它是一个元组,并且元组是不可变的)。例如,假设您有一个“mixin类”,它向某些动物子类添加功能,但不向其他子类添加功能:

class Animal(object):
    pass

class Dog(Animal):
    pass

class Cat(Animal):
    pass

class TalkMixin(object):
    def talk(self):
        print("I talk like a {0}".format(self.__class__.__name__))

if __name__ == "__main__":

    dog = Dog()
    cat = Cat()

    try:
        dog.talk() 
        cat.talk()
    except AttributeError:
        print("Great - the program raised AttributeError, as expected")

    # now, add the MixIn to the class "Dog", but not to the class
    # "Cat" - do this on the fly:
    old_dog_bases = Dog.__bases__
    Dog.__bases__ = (Animal, TalkMixin)

    # this should be successful!
    dog.talk()

    try:
        cat.talk()
    except AttributeError:
        print("As expected, cat.talk() raised AttributeError")

    # now do the same (add the mixin dynamically - via inheritance) to
    # the Cat
    old_cat_bases = Cat.__bases__
    Cat.__bases__ = (Animal, TalkMixin)

    # this should be successful!
    cat.talk()

    # Now, remove the mixin (drop from the inheritance) for both cats
    # and dogs:
    Dog.__bases__ = old_dog_bases
    Cat.__bases__ = old_cat_bases

    try:
        dog.talk()
        cat.talk()
    except AttributeError:
        print("as expected, they can no longer talk")

产生以下输出:

Great - the program raised AttributeError, as expected
I talk like a Dog
As expected, cat.talk() raised AttributeError
I talk like a Cat
as expected, they can no longer talk

很多人认为混音班是邪恶的。他们可能是对的!你可以想象,如果你把bases属性搞砸了,你的程序就毁了。所以,就是这样-您可以动态地更改对象的继承,但这并不意味着您应该(可能是抽象类或概念实现?)

相关问题 更多 >