Python类是否可以不从多个类继承,而是具有“选择"属性?继承? [英] Can a Python class not inherit from multiple classes, but have a "choice" of inheritance?
问题描述
我目前正在使用3Rd派对应用程序.该第三方应用定义了以下类别:
class VeryBaseClass(object):
def __init__():
pass
class BaseClass(VeryBaseClass):
def specific_method():
pass
然后,抢劫这些话题:
class Componenent[1,2,3,4....129883](BaseClass):
def other_specific_method():
pass
我无法修改任何这些类.因此,对于我来说,这里要覆盖/补充方法,我只需要创建一个从Component继承的类,即可在其中轻松地更改方法.
问题是,使MyComponent1,然后MyComponent2,MyComponent3等...全部用于在类的内容中复制粘贴完全相同的代码,并且仅更改继承是非常烦人的,而且根本不干! /p>
因此,有没有一种方法可以创建此类,例如:
class MyComponentGeneric(Component1, Component2, Component3....):
pass
根据我对实例的声明,MyComponentGeneric不会从列出的每个类中继承,但可以从一个或另一个类继承吗?
谢谢!
使用更具体的代码进行编辑:
实际上,我已经尝试过所有答案中涉及的内容,但我总是最终会遇到相同的错误:
我按照Chepney的建议建造了一家工厂:
# This method is the one I use as a replacement
def newrender(self, name, value, attrs=None):
result = super().render(name, value, attrs)
if self.image is None:
return result
else:
return '<img class="form-image" height="100" width="100" src="{}"/>'.format(self.image.url) + result
def MyWidgetFactory(widget, picture):
newclass = type("WithImage" + widget.__name__, (widget,), dict(render=newrender))
newclass.image = image
return newclass()
但是,一旦我的newrender方法启动,我就会收到此错误:
result = super().render(name, value, attrs)
RuntimeError: super(): __class__ cell not found
是因为工厂使用不当还是其他原因造成的?
5分钟后编辑 好的,我只需要通过用super(type(self),self)调用它来填充超级单元.不太确定它是如何工作的,但是,它起作用了!
谢谢大家!
这是字典的用例(如果字典键只是连续整数的序列,则可能是列表):
base_classes = {
1: Component1,
2: Component2,
# ...
}
def ComponentFactory(comp_type):
return base_classes(comp_type)()
在这里,ComponentFactory
为您创建实例,而不是创建一个新类,该类本质上只会包装一个现有类而不实际添加它.
如果您真的需要一种新类型,也可以在工厂中创建它:
def ComponentFactory(comp_type):
new_type = type('SomeTypeName', (base_classes[comp_type],), {})
return new_type()
但是,您可能应该注意,每个真实类只能创建一个一个这样的包装器,以免最终不会得到一堆相同的单例类.
I'm currently working with a 3Rd party app. This 3rd party app has thoses class defined :
class VeryBaseClass(object):
def __init__():
pass
class BaseClass(VeryBaseClass):
def specific_method():
pass
And then, looots of theses:
class Componenent[1,2,3,4....129883](BaseClass):
def other_specific_method():
pass
I can't modify any of these classes . So , for me to override/supplement methods here, I just have to create a class that inherits from Component, where I can change the methods effortlessly.
The problem is, making MyComponent1, then MyComponent2, MyComponent3, etc... all for copy-pasting the exact same code in the content of the class and just changing the inheritance is very annoying, and not DRY at all!
So, is there a way to create, for example , this class:
class MyComponentGeneric(Component1, Component2, Component3....):
pass
Where MyComponentGeneric would not inherit from EVERY class listed, but could inherit from one OR another, depending of my declaration of the instance ?
Thanks!
Edit with more concrete code :
Actually, I've tried things that belonged in every answer, but I always end up facing the same error :
I made a Factory as Chepney advised :
# This method is the one I use as a replacement
def newrender(self, name, value, attrs=None):
result = super().render(name, value, attrs)
if self.image is None:
return result
else:
return '<img class="form-image" height="100" width="100" src="{}"/>'.format(self.image.url) + result
def MyWidgetFactory(widget, picture):
newclass = type("WithImage" + widget.__name__, (widget,), dict(render=newrender))
newclass.image = image
return newclass()
But as soon as my newrender method launches, I get this error :
result = super().render(name, value, attrs)
RuntimeError: super(): __class__ cell not found
Is it because of a bad usage of the factory or something else ?
5 minutes later edit Okay, I just had to populate the super cell by calling it with super(type(self), self). Not quite sure how it works but, heh, it worked!
Thanks everyone !
This is a use case for a dictionary (or possibly a list, if the dictionary keys are just a sequence of consecutive integers):
base_classes = {
1: Component1,
2: Component2,
# ...
}
def ComponentFactory(comp_type):
return base_classes(comp_type)()
Here, ComponentFactory
creates the instance for you, rather than creating a new class that essentially would just wrap an existing class without actually adding to it.
If you really need a new type, you can create that in the factory as well:
def ComponentFactory(comp_type):
new_type = type('SomeTypeName', (base_classes[comp_type],), {})
return new_type()
However, you should probably take care that you only create one such wrapper per real class, so that you don't end up with a bunch of identical singleton classes.
这篇关于Python类是否可以不从多个类继承,而是具有“选择"属性?继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!