python基础第二十四节

魔法方法: Python中的魔法方法是一类特殊的方法, 它们以双下划线 __ 开头和结尾, 用于实现类的特殊行为.这些魔法方法在Python中具有特殊的含义, 可以让你自定义类的行为, 使其更符合你的需求, 它们一般是自动调用, 也可以通过内置函数来显式调用.

24.1 __new__和__del__

__new__ 是 Python 中的一个特殊魔法方法, 用于创建对象实例.它在对象实例被创建之前被调用, 通常用于控制对象的创建过程和自定义对象的创建方式.与之相对的是 __init__ 方法, 它在对象实例创建后进行初始化操作.
__new__的注意点:

  1. 返回实例对象: __new__ 方法必须返回一个类的实例对象.通常情况下, 它会调用父类的 __new__ 方法来创建实例, 并返回实例对象.
  2. 第一个参数是类: __new__ 方法的第一个参数是类本身, 通常命名为 cls.在调用时, Python 会自动传递类作为第一个参数.
  3. 控制实例创建过程: __new__ 方法允许你控制实例的创建过程.你可以在这个方法中实现自定义的逻辑.
    __del__当对象被释放的时候, 会执行. 它通常用于执行一些资源释放或清理操作, 如关闭文件、释放网络连接等. 但是, 但并不保证一定会调用, 因为垃圾回收可能由不同的策略来管理. python中对象的释放是一个比较复杂的过程. 一个对象有可能在引用到0的时候被释放, 且这个释放是可能在任意一个地方发生.
    注意:
    __del__跟python中的关键字del是没有关系的.del并不一定会触发__del__

24.2 __repr__和__len__

__repr__ 用于定义对象的字符串表示形式.
__str____repr__都返回一个对象的字符串描述, 不过两者的用途不同, str可以理解是给人阅读的, 而repr是给程序使用的.
print(obj)str(obj)方法调用对象的str方法;交互式CLI、repr(obj)、gdb调试时查看对象值返回的是repr, 不过和多情况下程序员把str和repr设置为一样__str__ == __repr__.
如果没有定义 __str__ 方法, 调用 print() 时会默认使用 __repr__ 方法.
__len__: 用于定义对象的长度(大小).当你在一个对象上调用内置的 len() 函数时, Python 会查找该对象是否定义了 __len__ 方法, 如果有则调用该方法并返回长度值.

24.3 __enter__和__exit__

上下文协议是一组特殊方法, 允许你创建可用于 with 语句的上下文管理器.使用上下文管理器可以在进入和退出代码块时执行特定操作, 如资源的分配和释放.Python 的上下文协议涉及两个主要的特殊方法:__enter____exit__.

  1. __enter__(self)
    
    方法:
    • 在进入代码块前被调用, 用于执行一些准备操作.
    • 可以返回一个值, 该值将被赋给 as 关键字之后的变量.
  2. __exit__(self, exc_type, exc_value, exc_traceback)
    
    方法:
    • 在退出代码块时调用, 无论代码块是否发生异常.
    • 可以用于执行一些清理操作, 如资源的释放.
    • 如果代码块内没有异常发生, 参数为 None, None, None.如果有异常, 参数包含异常类型、异常实例和跟踪信息.
    • 如果 __exit__ 方法返回 True, 异常不会向上继续传播.返回 False 则异常会继续向上抛.
      上下文协议的使用案例:可以使用 with 语句来管理文件的打开和关闭, 确保文件资源在退出代码块时被正确释放.

24.4 可迭代对象和迭代器

可迭代对象和迭代器是 Python 中用于遍历数据集合的概念.它们在很多情况下都用于实现数据的迭代操作, 如循环.
可迭代对象(Iterable)
可迭代对象是一种数据类型, 可以通过迭代获取其中的元素.在 Python 中, 任何实现了 __iter__() 方法的对象都被视为可迭代对象.常见的可迭代对象包括列表、元组、字典、集合、字符串等.
可迭代对象的特点:

  1. 可迭代对象是具有迭代性质的对象, 而迭代器是一个实现了迭代协议的对象.
  2. 可迭代对象可以通过 iter() 函数转换为迭代器.
  3. 迭代器是一种一次性的数据获取方式, 每次调用 next() 都会获取下一个元素.

24.5 中括号[]数据操作

__getitem____setitem____delitem__ 用于自定义对象的索引访问和操作.它们在创建自定义的容器类时非常有用, 允许你实现类似字典或列表的行为.

  1. __getitem__(self, key)
    这个方法定义了使用索引访问对象时的行为.当你像 obj[key] 这样使用索引操作时, Python 会调用对象的 __getitem__ 方法, 并将索引 key 作为参数传递给这个方法.你可以在这个方法中实现对应的行为, 比如从内部数据结构中获取相应的值.
  2. __setitem__(self, key, value)
    这个方法定义了使用索引赋值操作时的行为.当你像 obj[key] = value 这样进行索引赋值操作时, Python 会调用对象的 __setitem__ 方法, 并将索引 key 和值 value 作为参数传递给这个方法.你可以在这个方法中实现对应的赋值行为.
  3. __delitem__(self, key)
    这个方法定义了使用 del obj[key] 进行索引删除操作时的行为.当你使用 del 删除索引时, Python 会调用对象的 __delitem__ 方法, 并将索引 key 作为参数传递给这个方法.你可以在这个方法中实现删除操作的逻辑.
    这些方法的使用可以使你的自定义类更具像内置容器类型(如字典和列表)的行为, 从而实现更灵活和符合预期的数据操作.

25.6 __getattr____setattr____delattr__

__getattr____setattr____delattr__ 是 Python 中的魔法方法, 用于自定义对象的属性访问和操作.它们允许你控制属性的获取、设置和删除行为, 从而实现自定义的属性操作逻辑.

  1. __getattr__(self, name)
    当你访问一个不存在的属性时, Python 会调用对象的 __getattr__ 方法, 并将属性名 name 作为参数传递给这个方法.你可以在这个方法中实现对应的行为, 比如返回一个默认值或者抛出异常.
  2. __setattr__(self, name, value)
    当你设置属性的值时, Python 会调用对象的 __setattr__ 方法, 并将属性名 name 和值 value 作为参数传递给这个方法.你可以在这个方法中实现对应的赋值行为, 比如进行值的验证或修改.
  3. __delattr__(self, name)
    当你删除属性时, Python 会调用对象的 __delattr__ 方法, 并将属性名 name 作为参数传递给这个方法.你可以在这个方法中实现删除属性的逻辑.
    这些方法的使用可以使你的自定义类的属性操作更具控制性和灵活性.

24.7 可调用的

不仅 Python 函数是真正的可调用的, 任何 Python 对象都可以表现得像函数.为此, 只需实现魔法方法 __call__.
__call__ 是 Python 中的一个特殊魔法方法, 用于使对象可以像函数一样被调用.当一个对象被调用时, Python 会检查对象是否定义了 __call__ 方法, 如果定义了, 就会调用该方法, 从而实现对象的可调用行为.
这使得你可以将一个类的实例像函数一样使用, 提供更多的灵活性和自定义操作.

24.8 运算符

运算符魔法方法是用于实现对象之间的比较和关系运算的.它们允许你定义自定义的比较操作, 使你的对象可以像内置类型一样进行大小比较、相等性检查等操作.
下面是一些常用的运算符类型的魔法方法及其解释: