Python 冷门魔术方法小结

 更新时间:2025年04月16日 10:13:34   作者:予早随笔  
本文主要介绍了Python 冷门魔术方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

__init_subclass__

https://docs.python.org/3/reference/datamodel.html#object.__init_subclass__Python 3.6 新增。

父类派生子类后会调用该方法,方法中 cls 指向派生出的子类。

  • __init_subclass__被定义为普通方法,将会被隐式转换为类方法,故不必使用@classmethod装饰器
  • metaclass 不会被传给__init_subclass__
  • 传给一个新类的关键字参数会被传给父类的__init_subclass__。为保证与父类__init_subclass__兼容,应当将关键字参数中仅子类__init_subclass__需要的参数去掉后再传入父类__init_subclass__
class Base:
    def __init_subclass__(cls, /, name, **kwargs):
        super().__init_subclass__(**kwargs)
        print("Base __init_subclass__ called")
        cls.x = {}
        cls.name = name


class A(Base, name="Jack"):
    def __init__(self):
        super().__init__()
        print("A __init__ called")

    def __new__(cls, *args, **kwargs):
        super().__new__(cls)
        print("A __new__ called")


print(A.x)
print(A.name)
# Base __init_subclass__ called
# {}
# Jack
class A:
    def __init__(self):
        super().__init__()
        print("A __init__ called")

    def __new__(cls, *args, **kwargs):
        super().__new__(cls)
        print("A __new__ called")

    @classmethod
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__()
        print(kwargs)
        print("A __init_subclass__ called")


class B(A, bbb=12):
    def __init__(self):
        super().__init__()
        print("B __init__ called")

    def __new__(cls, *args, **kwargs):
        super().__new__(cls)
        print("B __new__ called")

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__()
        print("B __init_subclass__ called")


class C(B, ccc=12):
    def __init__(self):
        super().__init__()
        print("C __init__ called")

    def __new__(cls, *args, **kwargs):
        super().__new__(cls)
        print("C __new__ called")

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__()
        print("C __init_subclass__ called")

__class_getitem__

__class_getitem__方法的目的是允许标准库泛型类的运行时形参化以更方便地对这些类应用 类型提示。

  • __class_getitem__被定义为普通方法,将会被隐式转换为类方法,故不必使用@classmethod装饰器
  • __class_getitem__方法应当返回一个 GenericAlias 类型

https://docs.python.org/3/reference/datamodel.html#object.__class_getitem__

from typing import List


class A:

    def __class_getitem__(cls, item):
        print(item)
        return "abc"


print(A[0])

if __name__ == '__main__':
    int_arr_type = List[int]
    list1: int_arr_type = [1]
    list2: int_arr_type = []
    print(int_arr_type)

__instancecheck__与__subclasscheck__

  • __instancecheck__可以自定义实例检查逻辑
  • __subclasscheck__可以自定义子类检查逻辑
from typing import Any

class Meta(type):
    def __instancecheck__(self, instance: Any) -> bool:
        print("Instance Check")
        print(instance)
        return True

    def __subclasscheck__(self, subclass: type) -> bool:
        print("Subclass Check")
        print(subclass)
        if subclass is int:
            return True
        return False


class A(metaclass=Meta):
    pass


o = A()

print(isinstance(123, A))

print()

print(issubclass(int, A))

# Instance Check
# 123
# True
# 
# Subclass Check
# <class 'int'>
# True

__prepare__

https://peps.python.org/pep-3115

Python 3.0 新增。

__prepare__用于为类准备命名空间。

  • __prepare__定义在元类中并且必须被显式定义为类方法
  • __prepare__方法返回一个映射对象
  • Python 执行类定义语句,会首先调用其元类__prepare__方法,获得一个映射对象,该映射对象会被作为该类的命名空间,类的属性和方法会被存储在该映射对象中,随后映射对象会成为该类的__dict__属性。
import collections
from typing import Any, Mapping

# 创建一个 OrderedDict 对象作为字典
global_dict = collections.OrderedDict()

global_dict["global_dict_name"] = "global_dict"


class MyMeta(type):

    @classmethod
    def __prepare__(metacls, __name: str, __bases: tuple[type, ...], **kwargs: Any) -> Mapping[str, object]:
        print(metacls, __name, __bases, kwargs)
        return global_dict


class MyClass(metaclass=MyMeta):
    a = 1
    b = 2
    c = 3


print(MyClass.__dict__)
print("global_dict_name" in MyClass.__dict__)

# <class '__main__.MyMeta'> MyClass () {}
# {'global_dict_name': 'global_dict', '__module__': '__main__', '__firstlineno__': 18, 'a': 1, 'b': 2, 'c': 3, '__static_attributes__': (), '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None}
# True

__mro_entries__

https://docs.python.org/3/reference/datamodel.html#object.__mro_entries__

若某个类的父类不是type的实例(此时父类就是一个普通对象),则定义该类时其基类会被替换为父类中定义的__mro_entries__方法的返回值,若父类中没有定义__mro_entries__方法,此时类的定义会报错AttributeError: 'xxx' object has no attribute 'mro',因为无法进行MRO。

class A1:
    ...

class A2:
    def __mro_entries__(self, bases):
        return (dict,)

class B1(A1):
    print(type(A1), type(A1) is type)
    ...

class B2(A2()):
    print(type(A2()), type(A2()) is not type)
    ...

print(B1.mro())
print(B2.mro())
# <class 'type'> True
# <class '__main__.A2'> True
# [<class '__main__.B1'>, <class '__main__.A1'>, <class 'object'>]
# [<class '__main__.B2'>, <class 'dict'>, <class 'object'>]

到此这篇关于Python 冷门魔术方法小结的文章就介绍到这了,更多相关Python 冷门魔术方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • python基于opencv检测程序运行效率

    python基于opencv检测程序运行效率

    这篇文章主要介绍了python基于opencv检测程序运行效率,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • python  fire库的使用实例教程

    python  fire库的使用实例教程

    fire是python中用于生成命令行界面(Command Line Interfaces, CLIs)的工具,不需要做任何额外的工作,只需要从主模块中调用fire.Fire(),它会自动将你的代码转化为CLI,Fire()的参数可以说任何的python对象,对python fire库使用感兴趣的朋友一起看看吧
    2022-12-12
  • python解决12306登录验证码的实现

    python解决12306登录验证码的实现

    这篇文章主要介绍了python解决12306登录验证码的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Python help()函数用法详解

    Python help()函数用法详解

    这篇文章主要介绍了Python help()函数的作用,并举例说明它的详细用法,需要的朋友可以参考下
    2014-03-03
  • python智联招聘爬虫并导入到excel代码实例

    python智联招聘爬虫并导入到excel代码实例

    这篇文章主要介绍了python智联招聘爬虫并导入到excel代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例

    python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例

    这篇文章主要介绍了python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例,需要的朋友可以参考下
    2020-02-02
  • Python如何设置Excel单元格边框

    Python如何设置Excel单元格边框

    在数据驱动的业务场景中,自动化设置Excel单元格边框成为提升数据处理效率的关键环节,下面我们就来讲讲如何使用Python设置Excel工作簿中单元格的边框吧
    2025-04-04
  • python中注释用法简单示例

    python中注释用法简单示例

    注释即对程序代码的解释,在写程序时需适当使用注释,以方便自己和他人理解程序各部分的作用,下面这篇文章主要给大家介绍了关于python中注释用法的相关资料,需要的朋友可以参考下
    2023-02-02
  • python正则表达式完成车牌号检验的代码实例

    python正则表达式完成车牌号检验的代码实例

    这篇文章主要给大家介绍了关于python正则表达式完成车牌号检验的相关资料,在Python中正则表达式是一种用于匹配和操作字符串的强大工具,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • AI生成图片Stable Diffusion环境搭建与运行方法

    AI生成图片Stable Diffusion环境搭建与运行方法

    Stable Diffusion是一种基于扩散过程的生成模型,由Ge et al.在2021年提出,该模型利用了随机变量的稳定分布,通过递归地应用扩散过程来生成高质量的图像,这篇文章主要介绍了AI图片生成Stable Diffusion环境搭建与运行,需要的朋友可以参考下
    2023-05-05

最新评论