Python:如何继承和重写
考虑这种情况: 我得到一个Python:如何继承和重写,python,inheritance,overriding,Python,Inheritance,Overriding,考虑这种情况: 我得到一个A类型的对象,它具有f函数: class A: def f(self): print 'in f' def h(self): print 'in h' 我得到了这个类的一个实例,但我想覆盖f函数,同时保存A的其余功能。所以我当时的想法是这样的: class B(A): def __init__(self, a): #something here .... def f(self):
A
类型的对象,它具有f
函数:
class A:
def f(self):
print 'in f'
def h(self):
print 'in h'
我得到了这个类的一个实例,但我想覆盖f
函数,同时保存A
的其余功能。所以我当时的想法是这样的:
class B(A):
def __init__(self, a):
#something here
....
def f(self):
print 'in B->f'
其用法是:
def main(a):
b = B(a)
b.f() #prints "in B->f"
b.h() #print "in h"
我想要的是一种复制构造函数,它获取当前类的父类(a
),并返回该类的实例(B
)
你是怎么做这种事的?\uuuu init\uuu
方法看起来如何
注意:这篇文章由原始海报编辑,以包含评论中建议的更改,这就是为什么有些建议看起来多余或不正确的原因。尝试以下方法:
class A:
def f(self):
print("in f")
def h(self):
print("in h")
class B(A):
def f(self):
print("in B:f")
def test(x):
x.f()
x.h()
test(A())
test(B())
注意,我使用的是Python3,这就是print
将参数放在括号中的原因
输出:
in f
in h
in B:f
in h
对于python中的实例方法,需要将
self
参数放入参数列表中
一旦你做到了这一点,它就会起作用,因为所有的方法在python中都是虚拟的。你如何基于“类
A
中的一个”构造子类B
”的对象完全取决于后者如何保持状态(如果有的话),以及如何最好地达到该状态并复制它。在您的示例中,A
的实例是无状态的,因此您完全不需要在B
的中执行任何工作。在更典型的示例中,假设:
class A(object):
def __init__(self):
self._x = 23
self._y = 45
def f(self):
print 'in f,', self._x
def h(self):
print 'in h,', self._y
状态将位于两个实例属性\ux
和\uy
,因此您需要复制它们:
class B(A):
def __init__(self, a):
self._x = a._x
self._y = a._y
def f(self):
print 'in B->f,', self._x
这是最常见和最正常的方法,其中子类接受并直接实现其对超类的状态依赖——这是非常简单和线性的
通常,您会在A
的中查找的实例状态方面,因为大多数普通、简单的Python代码都会在初始化时建立实例状态(属性可能会在以后添加和删除,甚至从类体之外的代码中删除,但这并不常见,通常也不可取)
可以添加一点“魔力”(基于内省的编程),例如:
是类可以定义的一种特殊方法——如果它们定义了,则使用它(例如,通过酸洗)来“获取其实例的状态”,以便进行序列化(否则,实例的\uuu dict\uuu
被视为实例的“状态”)。它可能会返回一个dict(在这种情况下,.update
调用updatesself
的状态),但如果类还定义了一个接受它的\uuuu setstate\uuuuu
,它也可能会返回任何其他内容(因此该代码首先尝试该路由,然后返回到更新可能性)。请注意,在这个用例中,两种特殊方法中的一种或两种都将继承自A
——我不会在B
中定义/覆盖它们(当然,除非有其他微妙的目标需要通过这种方式实现;-)
用这四行“魔法”代替我最初建议的简单作业值得吗?大多数情况下,不,简单更可取。但是,如果A
做了任何特殊的事情,或者外部代码改变了它的状态,那么这个解决方案可以更强大、更通用(这就是你接受它的复杂性所购买的)。因此,您必须知道后一种情况是否适用(然后是特殊状态相关方法的“大炮”),或者A
及其实例是否是“非常普通的普通实例”,在这种情况下,我强烈建议您选择简单和清晰。它与OP的代码有什么不同?他似乎只忘记了self
。顺便问一下,python中的虚拟方法是什么意思?@Bunny Rabbit:Douglas的意思是virtual
,就像C++
一样,其中必须将方法显式定义为virtual
,以使其可重写。a
应该表示什么?Guy,您需要先阅读\uuuuu init\uuuu()
方法。不要把它和继承语法混淆了。这正是我想要的。谢谢+1-我今天读到的最有用的东西是:“取决于……后者如何保持状态,你如何……复制它”
class B1(A):
def __init__(self, a):
try: s = a.__getstate__()
except AttributeError: s = a.__dict__
try: self.__setstate__(s)
except AttributeError: self.__dict__.update(s)