总结学到的东西:
1.想让类的实例变成能够组成条件判断的语句,需添加__bool__方法,并返回布尔值
2.定义你的实例的比较,实现__eq__方法,有一个参数(other),并且返回一个布尔值
3.math.hypot接受一个二维向量并算它的模。
4.__iter__方法的实现让这个实例变成一个可迭代对象。也就是说可以for i in 实例了,也可以*实例。
那怎么实现呢?答:我们在这个函数返回一个生成器。
5.classmethod 的第一个参数总是类, 而staticmethod不是很有用。
6.format(str, '格式说明符')
格式说明符控制我们这个str的显示
如'b'表示二进制, '.1%'表示保留一位小数的百分率输出.
7.要把我们这个对象放入集合,首先这个对象得是个可散列的。
所以我们要实现__hash__
8.@property 装饰器是让方法变成属性一样的调用方式?
9.私有变量可以获取 a = A()
print(a._A__private)
Python的私有主要是防止继承时覆盖
10.不在方法内部定义的变量,例如我们定义了一个a。同时没有这个属性,则我们调用self.a会去调用这个类里定义的变量,虽然我们没有这个属性。但是内部有定义就不能这样调用了,只能用class.a去调用。
11.使用__slots__储存我们的属性,比如我们接下来要介绍的向量类,可以这样定义x,y
__slots__ = ('__x', '__y')
这样可以避免大的内存开销。
贴代码
import math from array import array class Vector2d: __slots__ =('__x', '__y') # def __init__(self, x, y): # self.__x = float(x) # self.__y = float(y) @property def x(self): return self.__x @property def y(self): return self.__y def __iter__(self): return (i for i in (self.x ,self.y)) def __repr__(self): classname = type(self).__name__ return '{}({!r}, {!r})'.format(classname, *self) def __str__(self): return str(tuple(self)) def __bytes__(self): return (bytes([ord(self.typecode)]) + bytes(array(self.typecode, self))) def __eq__(self, b): return tuple(self) == tuple(b) def __abs__(self): return math.hypot(self.x, self.y) def __bool__(self): return bool(abs(self)) @classmethod def __frombytes__(cls, octets): typecode = chr(octets[0]) memv = memoryview(octets[1:]).cast(typecode) return cls(*memv) def __format__(self, fmt_spec=""): componets = ( format(i, fmt_spec)for i in self) return '({}, {})'.format(*componets) def __format__(self, fmt_spec = ''): if fmt_spec.endswith('p'): fmt_spec = fmt_spec[:-1] coord = (abs(self), self.angle()) output_fmt = '<{}, {}>' else: coord = self output_fmt = '({}, {})' return output_fmt.format(*coord) def angle(self): return math.atan2(self.y, self.x) def __hash__(self): return hash(self.x) ^ hash(self.y) print(format(Vector2d(1,1), 'p'))