Python Cookbook 8类与对象(待补)

目录

 

8.1 改变对象的字符串显示

8.2 自定义字符串的格式化

8.3 让对象支持上下文管理协议

8.4 创建大量对象时节省内存方法

8.5 在类中封装属性名

8.6 创建可管理的属性

8.7 调用父类方法

8.8 子类中扩展property

8.9 创建新的类或实例属性

8.10 使用延迟计算属性

8.11 简化数据结构的初始化

8.12 定义接口或者抽象基类

8.13 实现数据模型的类型约束

8.19 实现状态对象或者状态机


8.1 改变对象的字符串显示

__str__()

__repr__()

Python 魔术(特殊)方法 https://blog.csdn.net/qq_42105144/article/details/103274416

8.2 自定义字符串的格式化

__format__()

8.3 让对象支持上下文管理协议

给类添加 __enter__()  和  __exit__() 方法

上下文管理器的行为由两种魔术方法确定:

object.__enter__(self) 是在with语句创建的代码块的开头应执行的操作。 with 语句将会绑定这个方法的返回值到 as 子句中指定的目标。

object.__exit__(self, exc_type, exc_value, traceback) 是在代码块已执行(或终止)之后应执行的操作。它可用于处理异常,执行清理或在执行块中的操作后立即执行总是执行的操作。
 

编写上下文管理器的主要原理是你的代码会放到 with 语句块中执行。 当出现 with 语句的时候,对象的 __enter__() 方法被触发, 它返回的值(如果有的话)会被赋值给 as 声明的变量。然后,with 语句块里面的代码开始执行。 最后,__exit__() 方法被触发进行清理工作。

不管 with 代码块中发生什么,上面的控制流都会执行完,就算代码块中发生了异常也是一样的(发生异常就直接转去执行__exit__ )。 事实上,__exit__() 方法的第三个参数包含了异常类型、异常值和追溯信息(如果有的话)。 __exit__() 方法能自己决定怎样利用这个异常信息,或者忽略它并返回一个None值。 如果 __exit__() 返回 True ,那么异常会被清空,就好像什么都没发生一样, with 语句后面的程序继续在正常执行。

3. with 语句上下文管理器

示例:13.13 实现一个计时器

8.4 创建大量对象时节省内存方法

对于主要是用来作为简单的数据结构的类而言,可以通过给类添加 __slots__ 属性来极大的减少实例所占的内存,如下一个作为日期的数据结构的类:

class Date:
    __slots__ = ['year', 'month', 'day']
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

不使用slots直接存储一个Date实例, 在64位的Python上面要占用428字节,而如果使用了slots,内存占用下降到156字节。 如果程序中需要同时创建大量的日期实例,那么这个就能极大的减小内存使用量了。

当定义 __slots__ 后,Python就会为实例使用一种更加紧凑的内部表示。 实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典,这跟元组或列表很类似。 在 __slots__ 中列出的属性名在内部被映射到这个数组的指定小标上。 使用slots一个不好的地方就是我们不能再给实例添加新的属性了,只能使用在 __slots__ 中定义的那些属性名。

https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p04_save_memory_when_create_large_number_instances.html

8.5 在类中封装属性名

两种不同的编码约定(单下划线和双下划线)来命名私有属性,限制访问

8.6 创建可管理的属性

怎么对类实例的属性增加除访问与修改之外的其他处理逻辑,比如类型检查或合法性验证?

@property

https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p06_create_managed_attributes.html

https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208

8.7 调用父类方法

super() 

非常全面:https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html

8.8 子类中扩展property

@property

https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p08_extending_property_in_subclass.html

8.9 创建新的类或实例属性

一个描述器就是一个实现了三个核心的属性访问操作(get, set, delete)的类, 分别为 __get__() 、__set__() 和 __delete__() 这三个特殊的方法。 

8.10 使用延迟计算属性

@property

8.11 简化数据结构的初始化

当需要使用大量很小的数据结构类的时候, 相比手工一个个定义 __init__() 方法而已,使用在基类中定义公用的 __init__() 函数这种方式可以大大简化代码,示例:

'''在基类结构中定义公用的 __init__() 函数
'''
>>> class Structure:
    #属性列表
    _fields = []
    def __init__(self,*args):
        if len(args) != len(self._fields):
            raise TypeErroe(f'Expected {len(self._fields)} attrs!')
        for f,v in zip(self._fields,args):
            #设置属性值
            setattr(self,f,v)

'''子类点'''            
>>> class Point(Structure):
    _fields = ['x','y']

    
>>> a = Point(10,15)
>>> a = Point(10,2,3)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    a = Point(10,2,3)
  File "<pyshell#1>", line 5, in __init__
    raise TypeErroe(f'Expected {len(self._fields)} attrs!')
NameError: name 'TypeErroe' is not defined

'''子类圆'''  
>>> class Circle(Structure):
	_fields = ['radius','x','y']

	
>>> c = Circle(3,10,15)
>>> c.radius
3

8.12 定义接口或者抽象基类

抽象基类的一个主要用途是在代码中检查某些类是否为特定类型,实现了特定接口

8.13 实现数据模型的类型约束

本节使用了很多高级技术,包括描述器、混入类、super() 的使用、类装饰器和元类。

 

 

8.19 实现状态对象或者状态机

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值