❶ klassmeth 返回全部位置参数。 ❷ statmeth 也是。 ❸ 不管怎样调用 Demo.klassmeth, 它的第一个参数始终是 Demo 类。 ❹ Demo.statmeth 的行为与普通的函数相似。
classmethod 装饰器非常有用, 但是我从未见过不得不用staticmethod 的情况。 如果想定义不需要与类交互的函数, 那么在模块中定义就好了。
可散列的vector
按照定义, 目前 Vector2d 实例是不可散列的, 因此不能放入集合
(set) 中:
>>> v1 = Vector2d(3, 4)
>>> hash(v1)
Traceback (most recent call last):
...
TypeError: unhashable type: 'Vector2d'
>>> set([v1])
Traceback (most recent call last):
...
TypeError: unhashable type: 'Vector2d'
为了把 Vector2d 实例变成可散列的, 必须使用 __hash__ 方法(还需
要 __eq__ 方法, 前面已经实现了) 。 此外, 还要让向量不可变, 详情
参见第 3 章的附注栏“什么是可散列的数据类型”。
目前, 我们可以为分量赋新值, 如 v1.x = 7, Vector2d 类的代码并
不阻止这么做。 我们想要的行为是这样的:
>>> v1.x, v1.y
(3.0, 4.0)
>>> v1.x = 7
Traceback (most recent call last):
...
AttributeError: can't set attribute
为此, 我们要把 x 和 y 分量设为只读特性, 如示例 9-7 所示。
示例 9-7 vector2d_v3.py: 这里只给出了让 Vector2d 不可变的代
码, 完整的代码清单在示例 9-9 中
class Vector2d:
typecode = 'd'
def __init__(self, x, y):
self.__x = float(x) ➊self.__y = float(y)