覆盖没有名称修改的继承方法[重复]
Posted
技术标签:
【中文标题】覆盖没有名称修改的继承方法[重复]【英文标题】:Overriding inherited method without name mangling [duplicate] 【发布时间】:2018-04-13 01:04:39 【问题描述】:注意:类似的问题 here,但我不认为这是完全重复的规范。
下面,我有两个类,一个继承自另一个。请注意,这些只是说明性的。
在_Pandas.array()
中,我想简单地将pandas DataFrame 包裹在从_Numpy.array()
返回的NumPy 数组周围。我知道我当前的代码有什么问题(_Pandas.array()
被重新定义,尝试调用自身并进行无限递归),但不知道如何在没有名称修改或父类上的准私有方法的情况下修复它。
import numpy as np
import pandas as pd
class _Numpy(object):
def __init__(self, x):
self.x = x
def array(self):
return np.array(self.x)
class _Pandas(_Numpy):
def __init__(self, x):
super(_Pandas, self).__init__(x)
def array(self):
return pd.DataFrame(self.array())
a = [[1, 2], [3, 4]]
_Pandas(a).array() # Intended result - pd.DataFrame(np.array(a))
# Infinite recursion as method shuffles back & forth
我知道我可以做类似的事情
class _Numpy(object):
def __init__(self, x):
self.x = x
def _array(self): # Changed to leading underscore
return np.array(self.x)
class _Pandas(_Numpy):
def __init__(self, x):
super().__init__(x)
def array(self):
return pd.DataFrame(self._array())
但这似乎很不理想。实际上,我经常使用_Numpy
——它不仅仅是一个通用的父类——而且我不想在它的所有方法前加上一个下划线。我还能怎么做呢?
【问题讨论】:
那么,您的.array
方法返回np.ndarray
还是pd.DataFrame
?这会破坏 Liskov 替换原则,不是吗?
@juanpa.arrivillaga _Numpy.array()
返回np.ndarray
,_Pandas.array()
返回pd.DataFrame
(或者至少我愿意)
是的,本质上,这意味着对于给定类型为真的任何属性,任何子类型都应该为真。在这种情况下,array
返回ndarray
的属性被违反。通常,您希望方法返回相同的类型,或者至少,返回类型应该是协变的。
@juanpa.arrivillaga 请参阅下面的答案,主要是我感兴趣的是一种无需每种方法的私有和公共版本即可解决此问题的方法。但这实际上似乎是一种常用的路线。
【参考方案1】:
嗯...只是想检查一下为什么在_Pandas类中你不直接调用super?
class _Pandas(_Numpy):
def __init__(self, x):
super(_Pandas,self).__init__(x)
def array(self):
return pd.DataFrame(super(_Pandas,self).array())
我试过了,得到了下面的结果,不知道是你想要的还是我错过了什么
a = [[1, 2], [3, 4]]
_Pandas(a).array()
0 1
0 1 2
1 3 4
【讨论】:
把它想象成调用一个普通的方法。很多时候你可能想显式调用你的超级方法而不在你的子方法中做任何事情。以上是关于覆盖没有名称修改的继承方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章