返回介绍

扩展方法:好的方式

发布于 2024-01-29 22:24:15 字数 1649 浏览 0 评论 0 收藏 0

我们这里真正想要做的事情是扩展最初的giveRaise,而不是完全替换它。在Python中做到这一点的好方式是,使用扩展的参数来直接调用其最初的版本,如下所示:

这段代码利用了这样一个事实:类方法总是可以在一个实例中调用(这是通常的方式,Python把该实例自动地发送给self参数),或者通过类来调用(较少见的方式,其中,我们必须手动地传递实例)。用更有象征性的术语来说,记住,如下的常规方法调用:

由Python自动地转换为如下的同等形式:

其中,包含了要运行的方法的类,由应用于该方法的继承搜索规则来确定。我们可以在自己的脚本中以任何一种形式来编写,但是,两种形式之间略有差异——如果你直接通过类来调用,必须记住手动的传递实例。不管哪种方式,方法总是需要一个主体实例,并且Python只是对通过实例调用的方式自动提供实例。对于通过类名调用的方式,你需要自己给self发送一个实例;对于giveRaise这样的一个方法的内部代码,self已经是调用的主体,并且由此将实例传递过去。

通过类直接调用有效地扰乱了继承,并且把调用沿着类树向上传递以运行一个特定的版本。在这个例子中,我们可以使用这一技术来调用Person中默认的giveRaise,即便该方法在Manager层级已经重新定义了。在某种意义上,我们必须按照这种通过Person的方式来调用,因为,Manager的giveRaise代码内部的self.giveRaise()可能会循环——由于self已经是一个Manager,self.giveRaise()将会再次解析为Manager.giveRaise,以此类推,直到可用内存耗尽。

“好”的版本似乎喜欢在代码上略有不同,但是,它会对未来的代码维护意义重大,因为giveRaise现在只在一个地方(Person的方法),将来需要修改的时候,我们只要修改一个版本。实际上,这种形式更直接地抓住了我们的本意——我们想要执行标准的giveRaise操作,但直接加上一个额外的奖金。这里是实现了本步骤的整个模块文件:

为了测试我们的Manager子类定制,我们还添加了self测试代码,它创建一个Manager,调用其方法,并且打印它。这里是新版本的输出:

这里一切看上去都很好:bob和sue和以前一样,并且当Manager tom加薪10%的时候,他实际上得到了20%(它的pay从$50K增加到了$60K),因为Manager中定制的giveRaise只是对他运行。还要注意到,测试代码的末尾如何把tom作为一个整体打印出来,按照Person的__str__中定义的漂亮格式来显示:Manager对象获取lastName,而__init__构造函数方法的代码通过继承“免费”从Person得到。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文