特殊属性
| 属性 | 含义 | 
|---|---|
| __name__ | 类,函数,方法等名字 | 
| __module__ | 类定义所在的模块名 | 
| __class__ | 对象或类所属的类 | 
| __base__ | 类的基类的元组,顺序为他们在基类中出现的顺序 | 
| __doc__ | 类, 函数的文档字符串, 如果没有定义则为None | 
| __mro__ | 类的mro, class.mro()返回的结果的保存在__mro__ 中 | 
| __dict__ | 类或实例的属性, 可写的字典 | 
查看属性
__dir__: 返回类或者对象的所有成员名称列表, dir()函数操作实例实例就是调用它.
如果dir()参数obj包括方法_dir__(), 该方法将被调用.如果参数obj不包含\_dir__(), 该方法将最大限度地收集属性信息.
dir(obj)对于不同类型的对象obj具有不同的行为:
- 如果对象是模块对象, 返回的列表包含模块的属性名和变量名
- 如果对象是类型或者说是类对象, 返回的列表包含类的属性名, 及它的祖先类的属性名
- 如果是类的实例- 有__dir__方法, 返回可迭代对象的返回值
- 没有__dir__方法, 则仅可能收集实例的属性名, 类的属性和祖先类的属性名
 
- 如果obj不写, 返回列表包含内容不同- 在模块中, 返回模块的属性和变量名
- 在函数中, 返回本地作用域的变量名
- 在方法中, 返回本地作用域的变量名
 
| 1 | # animal.py | 
魔术方法***
- 分类: - 创建, 初始化与销毁 
- 可视化 
- hash
- bool
- 运算符重载
- 容器和大小
- 可调用对象
- 上下文管理
- 反射
- 描述器
- 其他杂项
 
实例化
| 方法 | 意义 | 
|---|---|
| __new__ | 实例化一个对象 该方法需要返回一个值, 如果该值不是cls的实例, 则不会调用__init__该方法永远都是静态方法 | 
__new__方法很少使用,即使创建了该方法也会使用return super().__new__(cls)基类object的__new__方法来创建实例并返回
可视化
| 方法 | 意义 | 
|---|---|
| __str__ | str函数, format函数, print函数调用, 需要返回对象的字符串表达, 如果没有定义,就去调用__repr__方法返回字符串表达, 如果__repr__没有定义, 就直接返回对象的内存地址信息 | 
| __repr__ | 内建函数repr()对一个对象获取字符串表达 | 
| __bytes__ | bytes()函数调用, 返回一个对象的bytes表达, 即返回bytes对象 | 
| 1 | class A: | 
hash
| 方法 | 意义 | 
|---|---|
| __hash__ | 内建函数hash()调用的返回值,返回一个整数.如果定义这个方法该类的实例就可hash | 
| __eq__ | 对应== 操作符, 判断2个对象是否相等, 返回bool值 定义了这个方法, 如果不提供__hash__方法, 那么实例将不可hash了 | 
bool
| 方法 | 意义 | 
|---|---|
| __bool__ | 内建函数bool(), 或者对象放在逻辑表达式的位置, 调用这个函数返回布尔值没有定义__bool__(), 就找__len__返回长度,非0 为真 | 
上下文管理
文件IO操作可以对文件对象使用上下文管理,使用with。。as语法
| 1 | with open('test') as f: | 
仿照上例写一个自己的泪,实现上下文管理
| 1 | class Point: | 
提示属性错误,没有__exit__,看了需要这个属性
某些版本会显示没有__enter__
上下文管理对象
当一个对象同时实现了__enter__()和exit()方法,他就属于上下文管理的对象
__enter__ 进入于此对象相关的上下文,如果存在该方法,with语法会把该方法的返回值作为绑定到as之句中指定的变量上
__exit__退出与此对象相关的上下文
with可以开启一个上下文运行环境,在执行前做一些准备工作,执行后做一些收尾工作
注意,with 并不开启一个新的作用域
上下文管理是安全的
上下文应用场景
1.增强功能
在代码执行的前后增加代码, 以增强其功能.类似装饰器的功能
2.资源管理
打开了资源需要关闭, 例如文件对象, 网络连接,数据库连接等
3.权限验证
在执行代码之前,做权限验证,在__enter__
contextilb.contextmanager
他是一个装饰器是实现上下文管理器, 装饰一个函数, 而不是像类一样实现__enter__he __exit__方法
对下面的函数有要求:必须有yield, 也就是这个函数必须返回一个生成器,且只有yield一个值.
也就是这个装饰器接受一个生成器对象作为参数.
总结
如果业务逻辑简单可以使用函数加contextlib.contexmanager装饰器方式,如果业务复杂,用类的方式加__enter__和__exit__方法方便
反射
概述
运行时, 区别于编译时, 指的是程序被加载到内存中执行的时候
反射, reflection, 指的是运行时获取类型定义信息
一个对象能够在运行时,像照镜子一样,反射出其类型信息
简单说,在python中,能够通过一个对象,找出其type, class, attribute或method的能力, 称为反射或者和自身
具有反射能力的函数有type(), isinstance(), callable(), dir(), getattr()等
反射相关的函数和方法
| getattar | 通过name返回object的属性值.当属性不存在,将使用default返回, 如果没有default,则抛出attrbuteerro,name必须为字符串. | 
|---|---|
| setattar | object的属性存在,这覆盖, 不存在,新增 | 
| hasattat | 判断对象是否有这个名字的属性,name必须为字符串 | 
反射相关的魔术方法
__getattr__(), __setattr__(), __delattr__(), 三个魔术方法
实例属性会按照继承关系找, 如果找不到, 就会执行__getattar__()方法, 如果没有这个方法, 就会抛出
AttributeError异常表示找不到属性.
查找属性顺序为:
instance.__dict__ - > instance.__class__.__dict__ -> 继承的祖先类(直到object)的__dict__ – 找不到- >调用__getattr__()
