我有一个类设计,其中继承自某个Children
类的Parent
类只是在某些parameters
中有所不同,但Parent
类包含所有方法,它们使用parameters
作为类变量提供给Children
。换句话说,我的每个Child
类都由parameters
列表和Parent
类的继承完全描述。
所以,比方说,我有以下几个类:
class Parent():
def __init__(self, **kwargs):
for param in self.__class__.parameters:
self.setattr(param, kwargs.get(param))
def compare(self, other):
for param in self.__class__.parameters:
if self.getattr(param) != other.getattr(param):
return False
return True
class ChildA(Parent):
parameters = ["length", "height", "width"]
def __init__(self, **kwargs):
super().__init__(**kwargs)
class ChildB(Parent):
parameters = ["color", "taste"]
def __init__(self, **kwargs):
super().__init__(**kwargs)
我的实际类有点不同 - 我在Parent
类上有越来越复杂的方法,也有不同类型的参数 - 但这只是设计原则的一个最小例子。
由于Parent
类依赖于它的Children
来获得类变量parameters
,我想,我可能想在每个Child
类上强制执行类变量的存在。我已经读过,我通过使用元类来实现这一点。但我也读到大多数开发人员不需要使用元类,如果有疑问,你可能不需要它们。我之前从未使用过元类,因此我怀疑是否应该使用它们,因此根据提到的规则,我可能不需要元类。但另一方面,术语“元类”听起来与我的结构非常匹配,因为Parent
在某种意义上看起来真的可以被称为“元类”(技术上,不是终端技术的方式)元类在OOP中使用,但就以下方面而言:它完全描述了子类的行为。
所以,我想知道:是否有不同的(更好的)类设计来反映我的结构?我应该使用元类来强制存在parameters
,还是有更好的方法呢?或者我应该首先辞职,以便首先在Children类上强制执行parameters
类变量?
如果使用python3.6或更高版本,你可以使用__init_subclass__
来完成这个,我个人认为它比一个元类更好。
基于描述的用例的__init_subclass__
示例:
class Parent:
def __init_subclass__(cls):
if not hasattr(cls, 'parameters'):
raise TypeError(f'Subclass of {cls} does not have a parameters class attribute')
def __init__(self, **kwargs):
for param in self.__class__.parameters:
self.setattr(param, kwargs.get(param))
def compare(self, other):
for param in self.__class__.parameters:
if self.getattr(param) != other.getattr(param):
return False
return True
class GoodChild(Parent):
parameters = ['length', 'height', 'width']
class BadChild(Parent):
pass
这导致在创建TypeError
类时(而不是在实例化时)引发BadChild
异常:
TypeError: Subclass of <class '__main__.BadChild'> does not have a parameters class attribute