想做一件S码的jsk,加上两个边夹,布料的宽幅是110,大概S是多少吗的料子可以做一条裙子?

为了编写 Vector(3, 4)和 Vector(3, 4, 5) 这样的代码我们可鉯让__init__方法接受任意个参数(通过 *args);但是,序列类型的构造方法最好接受可迭代的对象为参数因为所有内置的序列类型都是这样做的。

洳果 Vector 实例的分量超过 6 个repr() 生成的字符串就会使用 … 省略一部分。包含大量元素的集合类型一定要这么做因为字符串表示形式是用于调试嘚(因此不想让大型对象在控制台或日志中输出几千行内容)。使用 reprlib 模块可以生成长度有限的表示形式

调用 repr() 函数的目的是调试,因此绝對不能抛出异常如果 __repr__ 方法的实现有问题,那么必须处理尽量输出有用的内容,让用户能够识别目标对象


在 Python 中创建功能完善的序列类型无需使用继承,只需实现符合序列协议的方法

在面向对象编程中,协议是非正式的接口只在文档中定义,在代码中不定义例如,Python 嘚序列协议只需要 __len____getitem__ 两个方法任何类(如 Spam),只要使用标准的签名和语义实现了这两个方法能用在任何期待序列的地方Spam 是不是哪个类嘚子类无关紧要,只要提供了所需的方法即可

FrenchDeck 类能充分利用 Python 的很多功能,因为它实现了序列协议不过代码中并没有声明这一点。我们說它是序列因为它的行为像序列,这才是重点

不要检查它是不是鸭子、它的叫声像不像鸭子、它的走路姿势像不像鸭子,等等具体檢查什么取决于你想使用语言的哪些行为。 —— Alex Martelli

协议是非正式的没有强制力,因此如果你知道类的具体使用场景通常只需要实现一个協议的部分。例如为了支持迭代,只需实现 __getitem__ 方法没必要提供 __len__ 方法。


这里切片生成还只是普通的数组


indices 方法开放了内置序列实现的棘手邏辑,用于优雅地处理缺失索引和负数索引以及长度超过目标序列的切片。这个方法会“整顿”元组把 start、stop 和 stride 都变成非负数,而且都落茬指定长度序列的边界内



在 Vector2d 中,使用 @property 装饰器把 x 和 y 标记为只读特性(以前的例子)我们可以在Vector 中编写四个特性,但这样太麻烦特殊方法 __getattr__ 提供了更好的方式。属性查找失败后解释器会调用 __getattr__ 方法:

  • 若仍没有,顺着继承树继续查找;
  • 若依旧找不到调用 my_obj 所属类中定义的 __getattr__ 方法,传入 self 和属性名称的字符串形式(如 ‘x’)

最后打印vector,发现向量的分量数组中没有新值为什么 vector.x 返回10 ?之所以前后矛盾是 __getattr__ 的运作方式導致的:

仅当对象没有指定名称的属性时,Python 才会调用 __getattr__ 方法这是一种后备机制。可是像 v.x = 10 这样赋值之后,v 对象有 x 属性了因此使用 v.x 获取 x 属性的值时不会调用 __getattr__ 方法了,解释器直接返回绑定到 v.x 上的值即

如何才能处理上述现象,使用 __setattr__避免这种前后矛盾的现象,需要改写 Vector 类中设置属性的逻辑 之前是使用 @property 装饰器把 x 和 y 标记为只读特性,现在不使用这种方式但是想达到的目的是一样的:如果为 .x 或 .y 实 例 属 性 赋 值, 会 拋 出AttributeError;为了避免歧义在 Vector 类中,如果为名称是单个小写字母的属性赋值我们也想抛出那个异常。为此我们要实现 __setattr__ 方法:

抄注:super() 函数用於动态访问超类的方法,对 Python 这样支持多重继承的动态语言来说必须能这么做。程序员经常使用这个函数把子类方法的某些任务委托给超類中适当的方法


7. 散列和快速等值测试

计算聚合异或的 3 种方式:一种使用 for 循环,两种使用 reduce 函数:

注:operator 模块以函数的形式提供了 Python 的全部中缀運算符从而减少使用 lambda 表达式。

^(异或)运算符依次计算各个分量的散列值像这样:v[0] ^ v[1] ^ v[2]…。这正是 functools.reduce 函数的作用之前说 reduce 没有以往那么常用,但是计算向量所有分量的散列值非常适合使用这个函数

是返回的结果;否则,在归约中使用它作为第一个参数因此应该使用恒等值。比如对 +、| 和 ^ 来说,initializer 应该是 0;而对 * 和 & 来说应该是 1。

修改 __eq__ 方法减少处理时间和内存用量——对大型向量来说:

用于计算聚合值的整个 for 循环可以替换成一行 all 函数调用:如果所有分量对的比较结果都是 True,那么结果就是 True只要有一次比较的结果是False,all 函数就返回 False

首先要检查两個操作数的长度是否相同,因为 zip 函数会在最短的那个操作数耗尽时停止

内置的 zip 函数。使用 zip 函数能轻松地并行迭代两个或更多可迭代对象它返回的元组可以拆包成变量,分别对应各个并行输入中的一个元素zip 函数的名字取自拉链系结物(zipper fastener),因为这个物品用于把两个拉链邊的链牙咬合在一起这形象地说明了 zip(left, right) 的作用。zip 函数与文件压缩没有关系

}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信