假设我有以下两个类
class A:
def own_method(self):
pass
def descendant_method(self):
pass
class B(A):
pass
我希望descendant_method
可以从B
的实例调用,而不是{
我可以想出几种解决办法,但都不令人满意:
NotImplementedError
:但这是在修改方法的运行时行为,我不想这样做
只要descendant_method
不使用A
的太多,否则我们将不得不继承{
A
中将方法设为私有并在元类中重新定义它:class A:
def own_method(self):
pass
def __descendant_method(self):
pass
class AMeta(type):
def __new__(mcs, name, parents, dct):
par = parents[0]
desc_method_private_name = '_{}__descendant_method'.format(par.__name__)
if desc_method_private_name in par.__dict__:
dct['descendant_method'] = par.__dict__[desc_method_private_name]
return super(AMeta, mcs).__new__(mcs, name, parents, dct)
class B(A, metaclass=AMeta):
def __init__(self):
super(B, self).__init__()
这是可行的,但显然看起来很脏,就像在B
中写self.descendant_method = self._A__descendant_method
。在
实现这种行为的正确“Python”方式是什么?在
UPD:将方法直接放在B
中当然可以,但是我希望A
将有许多后代使用此方法,并且不希望在每个子类中定义它。在
尝试使用
__class__.__name__
检查类名。在据我所知,这可能是实现你想要的最具Python式的方式:
另一种选择可能是:
^{pr2}$它们都是Python式的,因为它清晰、易读、清晰、简洁。在
在这些方法中选择一种将取决于您对用例的意图。在你的问题中举一个更具体的例子会很有帮助。在
让
AA
从A
继承有什么不好的?它基本上是一个抽象基类,它添加了A
中没有的附加功能。如果您真的不希望AA
被实例化,那么python的答案是不用担心它,只需记录用户不打算这样做。但是如果你真的坚持,你可以定义__new__
来在用户试图实例化AA
时抛出一个错误。在另一种选择可能是使
^{pr2}$AA
成为{a1}。要实现这一点,您需要至少定义一个方法作为抽象方法,__init__
可以这样做,如果没有其他方法您想说是抽象的。在最后,在
A
上使用子代方法有什么不好的,但是不使用它。您正在为A
编写代码,所以不要使用该方法。。。您甚至可以记录该方法,说明它并不打算由A
直接使用,而是可以用于子类。这样未来的开发人员就会知道你的意图。在相关问题 更多 >
编程相关推荐