魔术方法

特殊属性

属性 含义
__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
2
3
4
5
6
7
8
9
# animal.py
class Animal:
x = 123
def __init__(self, name):
self._name = name
self.__age = 10
self.weight = 20

print('animal Module\ s names = {}'.format(dir()))# 模块的属性 )

魔术方法***


  • 分类:

    • 创建, 初始化与销毁

    • 可视化

    • 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
2
3
4
5
6
class A:
def __init__(self, name, age = 18):
self.name = name
self.age = age
def __repr__(self):
return 'repr:{}{}'.format(self.name, self.age)

hash

方法 意义
__hash__ 内建函数hash()调用的返回值,返回一个整数.如果定义这个方法该类的实例就可hash
__eq__ 对应== 操作符, 判断2个对象是否相等, 返回bool值 定义了这个方法, 如果不提供__hash__方法, 那么实例将不可hash了

bool

方法 意义
__bool__ 内建函数bool(), 或者对象放在逻辑表达式的位置, 调用这个函数返回布尔值没有定义__bool__(), 就找__len__返回长度,非0 为真

上下文管理

文件IO操作可以对文件对象使用上下文管理,使用with。。as语法

1
2
with open('test') as f:
pass

仿照上例写一个自己的泪,实现上下文管理

1
2
3
4
class Point:
pass
with Point as p:
pass

提示属性错误,没有__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__()

感谢支持 !
0%