总结学到的东西:
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'))