Python 有没有一种方法可以动态创建子类?
我正在创建一个游戏,其中我有一个创建实体的复杂方法 加载一个级别时,加载代码将读取一组YAML文件,其中包含所有不同可能单元的属性。使用YAML文件,它创建一个所谓的Python 有没有一种方法可以动态创建子类?,python,class,singleton,subclass,subclassing,Python,Class,Singleton,Subclass,Subclassing,我正在创建一个游戏,其中我有一个创建实体的复杂方法 加载一个级别时,加载代码将读取一组YAML文件,其中包含所有不同可能单元的属性。使用YAML文件,它创建一个所谓的EntityResource对象。此EntityResource对象在生成新单位时充当权威信息源。目标有两个: 通过对YAML文件的输出执行哈希检查来阻止欺骗 通过让所有单元信息来自一个单一的权威来源来帮助调试 然后将这些EntityResource对象送入EntityFactory对象,以生成特定类型的单元 我的问题如下。是否有一
EntityResource
对象。此EntityResource对象在生成新单位时充当权威信息源。目标有两个:
EntityResource
对象送入EntityFactory
对象,以生成特定类型的单元
我的问题如下。是否有一种方法可以根据正在读取的YAML文件的内容动态创建EntityResource
的子案例
另外,我希望这些YAML文件派生的子类中的每一个都被分配一个单例元类。有什么需要注意的吗?当我听到“动态创建子类”时,我理解为“动态创建行为不同的对象”,这实际上是一个配置问题
有没有什么东西是你仅仅通过读取一些数据并创建一个对象来决定它将如何根据读取的内容进行操作而得不到的
这是一个比喻:我是一个手巧的人——我可以把你扔给我的任何宜家家具组装起来。但每次我都不是一个不同的人,我只是一个手巧的人,阅读不同的图表,寻找不同种类的螺丝和木头。这就是我认为子类化不是这里的自然解决方案的原因。我不确定这是否是您想要的,但您可以使用动态创建子类:
SubClass = type('SubClass', (EntityResource,), {})
编辑:要理解type
是如何工作的,您只需翻译如何编写类并将其转换为type
调用。例如,如果您想编写以下内容:
class SubClass(EntityResource):
A=1
B=2
然后,这将转化为:
SubClass = type('SubClass', (EntityResource,), {'A': 1, 'B': 2})
其中:
- 第一个参数只是类名
- 第二个参数是父类列表
- 第三个参数是字典初始化类对象。这不仅包括类属性,还包括方法
- 可以动态创建子类。这并不意味着你应该这样做。无论如何,我会提供一个机制
每个类中的base属性告诉您继承链:
class Animal(object):
pass
class Dog(Animal):
pass
print Animal.__bases__
print Dog.__bases__
# prints:
#(<type 'object'>,)
#(<class '__main__.Animal'>,)
生成以下输出:
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
很多人认为混合班是邪恶的。他们可能是对的!你可以想象,如果你把属性搞砸了,你几乎毁了你的程序。所以,就是这样-您可以动态更改对象的继承,但这并不意味着您应该(可能是抽象类或概念实现?您是否回顾了这个问题?单例元类是什么意思?@abki我没有。现在阅读…我需要的是,通过创建具有不同值的对象无法完成的事情是使对象成为单例对象。我希望每个单元类型都有一个且只有一个
EntityResource
实例。这也是可以解决的。您已经需要跟踪已创建的子类,这样就不会重新创建它们,对吗?不必创建类,也不必将每个类都设置为单例,而是可以创建对象,保留由单元类型引用的对象表,并在创建时确保对象不是现有配置的副本。使用单例的想法是,我不需要跟踪已创建的类。我可以遍历目录的内容并开始构建对象。解决方案的问题在于,它需要代码显式检查重复项。这是一个事后检查,而不是一个先验的禁止。当你绝对地、肯定地需要一个类的单个实例时,没有任何东西可以取代单个实例。这似乎就是我所需要的。你会有一个更完整的例子吗?我发现python文档有点混乱…@blz我添加了更详细的解释。我希望这能有所帮助。我尝试了这个,但我得到了一个类型错误:一个新样式的类不能只有经典的基。将object
添加到父类元组似乎可以解决这个问题。这似乎是正确的解决方案吗?@blz我不知道这个限制。请注意,自python 2.2以来,新样式的类就一直存在。因此,除非您使用的是遗留代码,否则您应该使用它们。更多信息在此相关。我们可以动态删除子类;假设我稍后在程序中调用delSubClass
,但仍然EntityResource
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