目录
本章的目的是说明,如何使用特殊方法和约定的结构,定义行为良好且符合 Python 风格的类。
本章的特殊方法:
所有用于获取字符串和字节序列表示形式的方法:__repr__、__str__、__format__ 和 __bytes__。
把对象转换成数字的几个方法:__abs__、__bool__和 __hash__。
用于测试字节序列转换和支持散列(连同 __hash__ 方法)的 __eq__ 运算符。
1.用特殊方法实现一个2D向量类
>>> from array import array
>>> import math
>>> class Vector2d:
typecode = 'd'
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def __iter__(self):
return (i for i in (self.x, self.y))
def __repr__(self):
class_name = type(self).__name__
return '{}({!r}, {!r})'.format(class_name, *self)
def __str__(self):
return str(tuple(self))
def __bytes__(self):
return (bytes([ord(self.typecode)]) + bytes(array(self.typecode, self)))
def __eq__(self, other):
return tuple(self) == tuple(other)
def __abs__(self):
return math.hypot(self.x, self.y)
def __bool__(self):
return bool(abs(self))
Vector2d类实例具有的基本行为:
>>> v = Vector2d(10,20)
支持迭代
>>> for i in v:
print(i)
10.0
20.0
>>> x,y = v
>>> x,y
(10.0, 20.0)
支持显示信息
>>> v
Vector2d(10.0, 20.0)
>>> str(v)
'(10.0, 20.0)'
支持返回对象的字节表现形式
>>> bytes(v)
b'd\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x004@'
支持==比较
>>> vn = Vector2d(10,20)
>>> v == vn
True
支持求向量的模
>>> abs(v)
22.360679774997898
支持向量的模布尔运算
>>> bool(v)
True
2.classmethod与staticmethod
@
classmethod
把一个方法封装成类方法。
一个类方法把类自己作为第一个实参,就像一个实例方法把实例自己作为第一个实参。
@
staticmethod
将方法转换为静态方法。
静态方法不会接收隐式的第一个参数。要声明一个静态方法,请使用此语法
3.格式化显示
4.私有属性和“受保护的”属性
Python 文档把使用一个下划线前缀标记的属性称为“受保护的”属性。Python 解释器不会对使用单个下划线的属性名做特殊处理,不过这是很多 Python 程序员严格遵守的约定,他们不会在类外部访问这种属性。
5.使用 __slots__ 类属性节省空间
6. 覆盖类属性
在Python里面,类方法或者属性如果以双下划线开头,那么他们就是类的私有方法,在被继承的时候,即使子类有相同名字的以双下划线开头的属性或者方法也不会覆盖父类。
而且这些以双下划线开头的私有方法或者属性,在类内部可以自由被其他方法调用,但是在实例对象里面是不能直接调用的.