Python:如何继承和重写
考虑这种情况:
我得到一个 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
)。
你怎么做这样的事? __init__
方法看起来如何?
注意:这篇文章已由原始发布者编辑,以纳入评论中建议的更改,这就是为什么某些建议看起来多余或不正确的原因。
Consider this situation:
I get an object of type A
which has the function f
:
class A:
def f(self):
print 'in f'
def h(self):
print 'in h'
and I get an instance of this class, but I want to override the f
function, yet save the rest of the functionality of A
. So what I was thinking was something of the sort:
class B(A):
def __init__(self, a):
#something here
....
def f(self):
print 'in B->f'
and the usage would be:
def main(a):
b = B(a)
b.f() #prints "in B->f"
b.h() #print "in h"
What I want is a sort of copy constructor that gets a parent of the current class (A
), and returns an instance of this class (B
).
How do you do such a thing? How would the __init__
method look?
Note: this post has been edited by the original poster to incorporate changes suggested in the comments, which is why some of the suggestions look redundant or incorrect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如何“基于”类
A
之一构造子类B
的对象完全取决于后者如何保持状态(如果有),以及你如何最好地到达该状态并将其复制过来。在您的示例中,A
的实例是无状态的,因此您绝对不需要在B
的'__init__'
中执行任何操作。在一个更典型的示例中,假设:状态位于两个实例属性
_x
和_y
中,因此您需要复制这些:这是最常见的和正常的方法,子类接受并直接实现其对超类的状态依赖——它非常简单和线性。
您通常会在
A
的'__init__'
中查找A
的实例状态方面,因为大多数正常、简单的 Python 代码在以下位置建立实例状态:初始化(属性可能稍后添加和删除,甚至可以从类主体之外的代码中添加和删除,但这并不常见,通常也不建议)。可以添加一点“魔法”(基于内省的编程),例如:
getstate 是类可以定义的特殊方法 - 如果它们这样做,则将其用于(例如通过 pickling)“获取其实例的状态”以用于序列化目的(否则,实例的 __dict__ 被视为实例的“状态”)。它可能会返回一个字典(在这种情况下,
.update
调用会更新self
的状态),但如果该类还定义了一个,它也可能返回任何其他内容__setstate__
接受它(因此此代码首先尝试该路由,然后再返回到更新可能性)。请注意,在这个用例中,一个或两个特殊方法将从A
继承 - 我不会在B
中定义/覆盖它们(除非有进一步微妙的变化)当然,要以这种方式实现目标;-)。是否值得使用这四行“魔法”来代替我首先建议的简单作业?大多数情况下,不——简单更好。但是,如果
A
做了任何特殊的事情或者受到外部代码改变其状态的影响,那么这个解决方案可能会更强大和更通用(这就是您通过接受其复杂性而得到的结果)。因此,您必须知道后一种情况是否适用(然后“使用与状态相关的特殊方法的大枪”),或者A
及其实例是否是“非常正常的普通实例” ,在这种情况下,我强烈建议选择简单和清晰。How you construct an object of subclass
B
"based on" one of classA
depends exclusively on how the latter keeps state, if any, and how do you best get to that state and copy it over. In your example, instances ofA
are stateless, therefore there is absolutely no work you need to do inB
's'__init__'
. In a more typical example, say:the state would be in the two instance attributes
_x
and_y
, so those are what you need to copy over:This is the most common and normal approach, where the subclass accepts and directly implements its state-dependence on the superclass -- it's very straightforward and linear.
You normally look for
A
's instance state aspects inA
's'__init__'
, because most normal, straightforward Python code establishes instance state at initialization (attributes might be added and removed later, or even from code outside of the class's body, but that's not common and generally not advisable).It is possible to add a little touch of "magic" (introspection-based programming), e.g...:
getstate is a special method that classes may define -- if they do, it's used (e.g. by pickling) to "get the state" of their instances for serialization purpose (otherwise, the instance's
__dict__
is deemed to be the instance's "state"). It may return a dict (in which case the.update
call updatesself
's state), but it may also return anything else if the class also defines a__setstate__
that accepts it (so this code tries that route first, before falling back to the update possibility). Note that in this use case either or both of the special methods would be inherited fromA
-- I wouldn't define / override them inB
(unless there are further subtle goals to be achieved that way of course;-).Is it worth using these four lines of "magic" in lieu of the simple assignments I first suggested? Mostly, no -- simplicity is preferable. But if
A
does anything special or is subject to external code altering its state, this solution can be more powerful and general (that's what you're buying by accepting its complication). So, you have to know if the latter case applies (and then "go for the big guns" of the special state-related methods), or ifA
and its instances are "pretty normal vanilla ones", in which case I would strongly recommend choosing simplicity and clarity instead.试试这个:
注意,我使用的是 Python 3,这就是
print
采用括号中的参数的原因。输出:
Try this:
Note, I'm using Python 3, which is the reason for
print
taking the arguments in parenthesis.Output:
对于 Python 中的实例方法,您需要将 self 参数放入参数列表中。
一旦你这样做了,它就会起作用,因为所有方法在 python 中都是虚拟的。
You need to put the
self
argument into the argument list for instance methods in python.Once you've done that, it will just work, because all methods are virtual in python.