返回介绍

第六部分 类和 OOP

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

参考第31章 第六部分 练习题 的习题。

1.继承。下面是这个练习题的解答(adder.py文件),以及一些交互模式下的测试。__add__重载方法只出现一次,就是在超类中,因为它调用了子类中类型特定的add方法:

在最后的测试中,得到表达式错误,因为+的右边出现类实例。如果你想修复它,可使用__radd__方法,就像第29章所描述的那样。

如果你在实例中保存一个值,可能也想重写add方法使其只带一个自变量(按照第六部分中其他例子的精神):

因为值是附加在对象上而不是到处传递,这个版本更加地面向对象。一旦你了解了,可能会发现,可以舍弃add,而在两个子类中定义类型特定的__add__方法。

2.运算符重载。答案中(文件mylist.py)使用的一些运算符重载方法,书中没有多谈,但它们应该是很容易理解的。复制构造函数中的初始值很重要,因为它是可变的。你不会想修改或者拥有可能被类外其他地方共享的对象参照值。__getattr__方法把调用转给包装列表。有关以Python 2.2以及后续版本编写这个代码的更为容易方式的提示,可以参考第31章:

要注意,通过附加而不是分片复制初值是很重要的,否则结果就不是真正的列表,也就不会响应预期的列表方法,例如,append(例如,对字符串进行分片运算会传回另一字符串,而不是列表)。你可以通过分片运算复制MyList的初值,因为其类重载了分片运算,而且提供预期的列表接口。然而,你需要避免对对象(例如字符串)做分片式的复制。此外,集合已经是Python的内置类型,这大体上只是编写代码的练习而已(参考第5章有关集合的细节)。

3.子类。解答如下所示(mysub.py)。你的答案应该也类似:

4.元类方法。注意,在Python 2.6中,运算符尝试通过__getattr__取得属性。你需要返回一个值使其能够工作。警告:正如第30章所提到的,__getattr__不会在Python 3.0中针对内置操作而调用,因此,如下的表达式不会像介绍的那样工作;在Python 3.0中,像这样的一个类必须显式地重新定义__X__运算符重载方法。关于这一点的更多介绍,参见第30章、第37章和第38章:

5.集合对象。下面是应得到的交互模式下的结果。注释说明了调用的是哪个方法:

对多个操作对象扩展的子类的解答,就像下面的类(multiset.py文件)一样。只需要取代最初集合中的两个方法。类的文档字符串说明了其工作原理:

与扩展的交互应该像下面所演示的。你可以使用&或调用intersect来做交集,但是对三个或以上的操作数,则必须调用intersect。&是二元(两边)运算符。此外,如果我们使用setwrapper.Set来引用multiset中的最初的类,那么也可以把MultiSet称为Set,让这样的改变变得更加透明。

6.类树链接。下面是修改Lister类的方法,并重新运行测试来显示其格式。对于基于dir的版本做同样的事情,并且当在树爬升变体中格式化类对象的时候也这么做:

7.组合。解答如下(lunch.py文件),注释混在代码中。这可能是用Python描述问题比英文更简单的情况之一:

8.动物园动物继承层次。下面是用Python编写的动物分类(zoo.py文件)。这是人工分法,这种通用化的编写代码模式适用于许多真实的结构,可以从GUI到员工数据库。Animal中引用的self.speak会触发独立的继承搜索,找到子类内的speak。通过交互模式测试这个练习题。试着用新类扩展这个层次,并在树中创建各种类的实例:

9.描绘死鹦鹉。下面程序是我实现这道题的方法(parrot.py文件)。Actor超类的line方法的运作方式:读取self属性两次,让Python传回该实例两次。因此,会启动两次继承搜索(self.name和self.says()会在特定的子类内找到信息):

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

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

发布评论

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