fluent Python读书笔记 符合Python风格的对象

总结学到的东西:

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'))

    

猜你喜欢

转载自blog.csdn.net/weixin_41958153/article/details/80629224