Understanding Python metaclasses

Python中的metaclass,不懂就不能说会phthon 在Python中,元类(metaclass)是一种高级概念 ,用于控制类的创建过程。简单来说,元类就是“类的类”,它负责生成我们日常使用的类对象 阅读详情

原文地址:https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/

译文参考:https://blog.youkuaiyun.com/wwx890208/article/details/80644400

国外的一位程序员(Ionel)在网上看了很多讲述Python元类的文章,但觉得没有一篇能讲明白元类在Python中是如何工作的,所以 Ionel 写了这篇文章,给出了自己的理解。

Python中,元类是一个充满争议的话题,很多开发者都避免使用元类。我认为导致这种现象的主要原因是,Python学习过程中没有很好地理解清楚Python灵活的工作流和查找规则。您需要理解一些关键的概念,才能在Python中有效地使用元类。

如果您以前没听过元类,那么简单来说,元类提供了很多有趣的途径,来减少模版的使用,并提供更加友好的API。为了使本文尽可能精炼,我假设读者们都富有创造性,这样我就不需要花大量的篇幅去解释:“为什么A需要用元类来实现,而B不需要?”。

本文使用Python 3,如果有Python 2值得注意的地方,会在脚注中用小字说明(脚注没翻译,看原文吧)。

概述

在深入讨论细节之前,我们有必要先作一个概括性的说明。

在Python中,类也是对象。与普通对象一样,类也是某个东西的实例——那就是元类。默认的元类是 type。不幸的是,为了能向后兼容, type有点难以理解: type可以作为一个函数使用,返回对象所属的类。

>>> class Foobar:
...     pass
...
>>> type(Foobar)
<class 'type'>
>>> foo = Foobar()
>>> type(foo)
<class '__main__.Foobar'>

如果熟悉内置函数 isinstance,您应该知道:

>>> isinstance(foo, Foobar)
True
>>> isinstance(Foobar, type)
True

上述关系如图所示:

在这里插入图片描述

让我们继续回到类的创建上来……

元类的简单使用

创建类时,我们可以完全不用 class声明语句,而是用 type来直接创建:

>>> MyClass = type('MyClass', (), {})
>>> MyClass
<class '__main__.MyClass'>

class声明不仅仅是语法糖,它还做了很多额外的工作,比如设置恰当的 __qualname__、 __doc__属性,以及调用 __prepare__方法等。

我们可以自定义一个元类:

>>> class Meta(type):
...     pass

然后使用它:

>>> class Complex(metaclass=Meta):
...     pass
>>> type(Complex)
<class '__main__.Meta'>

现在,我们对元类的使用有了大概的了解……

魔法方法

魔法方法是Python的特性之一,它允许开发人员重载各种操作符以及对象的行为。您可以这样做,来重载调用操作符:

>>> class Funky:
...     def __call__(self):
...         print("Look at me, I work like a function!")
>>> f = Funky()
>>> f()
Look at me, I work like a function!

元类的实现依赖于魔法方法,因此我们需要对这些魔法方法有所了解。

slots

当您在类中定义一个魔法方法时,此方法最终会成为描述该类的结构体中的一个指针,并放入 __dict__。对每个魔法方法,这个结构体中都有对应的字段。出于一些原因,这些字段被称为 type slots 。

而Python通过 __slots__属性实现了另外一个特性。带有 __slots__属性的类,创建的实例是没有 __dict__属性的(这样实例占的内存会少一丁点)。随之而来的副作用也很明显,除了 __slots__中指定的属性,实例不能再拥有其他属性:如果尝试给实例设置一个不在 __slots__中的属性,Python会抛出异常。

需要注意是,本文提到的 slots ,指的都是 type slots ,而不是 __slots__。

对象属性查找

这里很容易出错,因为和Python 2的经典类相比,Python 3新式类的实现有了很多细微的差别。

这里假设 Class是一个类, instance是类 Class的一个实例(为了和下一节区别,这里可理解为: instance是一个实例对象),那么引用 instance.foobar属性时的查找流程大致如下:

  • 调用 Class.__getattribute__( tp_getattro)对应的 type slot 。此方法的默认实现如下:

    • Class.__dict__中是否存在名为 foobar的元素,此元素有 __get__方法,且是数据描述符?
      • 若存在,返回 Class.__dict__['foobar'].__get__(instance, Class)的返回值。
    • instance.__dict__中是否存在名为 foobar的元素?
      • 若存在,返回 instance.__dict__['foobar']。
    • Class.__dict__中是否存在名为 foobar的元素,此元素有 __get__方法,但不是数据描述符?
      • 若存在,返回 Class.__dict__['foobar'].__get__(instance, Class)的返回值。
    • Class.__dict__中是否存在名为 foobar的元素?
      • 若存在,则返回 Class.__dict__['foobar']。
  • 若仍未找到 foobar,但存在 Class.__getattr__,则调用 Class.__getattr__('foobar')并返回。

如果还不清楚,可参考下图,下图展示了对象属性查找的整个过程:

在这里插入图片描述

为了避免点号 “.” 造成混淆,图里使用冒号 “:” 表示所处位置。

类属性查找

由于类需要支持类方法和静态方法,所以和引用对象属性( instance.foobar)的查找流程相比,引用类属性( Class.foobar)时的查找流程略有不同。

假设 Class是 Metaclass的一个实例(为了和上一节区别,这里可理解为: Class是一个类对象),引用 Class.foobar时的流程大致如下:

  • 调用 Metaclass.__getattribute__( tp_getattro)对应的 type slot 。此方法的默认实现如下:

    • Metaclass.__dict__中是否存在名为 foobar的元素,此元素有 __get__方法,且是数据描述符?
      • 若存在,返回 Metaclass.__dict__['foobar'].__get__(Class, Metaclass)的返回值。
    • Class.__dict__中是否存在名为 foobar的元素,且此元素是描述符(数据/非数据描述符)?
      • 若存在,返回 Class.__dict__['foobar'].__get__(None, Class)的返回值。
    • Class.__dict__中是否存在名为foobar的元素?
      • 若存在,返回 Class.__dict__['foobar']。
    • Metaclass.__dict__中是否存在名为 foobar的元素,但此元素不是数据描述符?
      • 若存在,返回 Metaclass.__dict__['foobar'].__get__(Class, Metaclass)的返回值。
    • Metaclass.__dict__中是否存在名为foobar的元素?
      • 若存在,则返回 Metaclass.__dict__['foobar']。
  • 若仍未找到 foobar属性,但存在 Metaclass.__getattr__,则调用 Metaclass.__getattr__('foobar')并返回。

整个流程如下图所示:

在这里插入图片描述

为了避免点号 “.” 造成混淆,图里使用冒号 “:” 表示所处位置。

魔法方法查找

魔方方法的查找是在类上完成的,直接使用类的大结构体的 slots。

  • 对象的类中是否存在此魔法方法对应的 slot (C代码大致如下: object->ob_type->tp_<magicmethod>)?

    • 若存在,则直接使用。
    • 否则,对应的指针为 NULL,表示不支持此魔法方法对应的操作。

    内部C代码的含义:

    • object->ob_type表示 object 对应的类。
    • ob_type->tp_<magicmethod>表示 type slot 。

上述流程看似简单,实际上 type slots 指向的是包装器,包装器包装您自定义的函数,因此描述符才能按照预期工作:

>>> class Magic:
...     @property
...     def __repr__(self):
...         def inner():
...             return "It works!"
...         return inner
...
>>> repr(Magic())
'It works!'

这就是魔方方法的实现。那么,有没有不遵守上述流程,以不同的方式来查找 slot 的呢?很遗憾,答案是 Yes ,让我们继续……

__new__方法

__new__方法是类和元类之间最容易混淆的方法之一。__new__方法有些非常特殊的约定。

__new__方法是一种构造器(它返回新的实例),__init__方法只是一个初始化程序(当 __init__被调用时,实例已经创建好了)。

假设有个类,定义如下:

class Foobar:
    def __new__(cls):
        return super().__new__(cls)

如果您学习过上一节,会觉得应该在元类上查找 __new__方法。不过遗憾的是,如果这样查找的话,__new__的作用将大大减弱,而实际上,__new__方法是静态查找的。

当 Foobar类需要使用这个魔法方法时,它会在当前的对象(即 Foobar类)上查找,而不像其他魔法方法,在其上一层查找。理解这一点非常重要,因为类和元类都可以定义 __new__方法。

  • Foobar.__new__被用来创建 Foobar的实例
  • type.__new__被用来创建 Foobar类(type的一个实例)

__prepare__方法

__prepare__方法在 class主体执行前调用,且必须返回一个类字典(dict-like)的对象,此对象被当作一个局部命名空间,这个命名空间包含了 class主体的所有代码。此方法是Python 3.0新增的功能,详见PEP-3115。

如果您自定义的 __prepare__返回一个对象 x,那么下面这段代码:

class Class(metaclass=Meta):
    a = 1
    b = 2
    c = 3

会这样修改 x:

x['a'] = 1
x['b'] = 2
x['c'] = 3

这个 x对象需要看起来像一个字典。需要注意的是,这个 x对象最终会成为 Metaclass.__new__方法的一个参数,并且如果它不是 dict的实例,您还需要在调用 super().__new__前手动转换它。

有趣的是,__prepare__与 __new__不同,并没有特殊的查找方式。似乎它没有属于自己的 type slot ,但如果您阅读过前面的章节,就会知道,__prepare__的查找是通过类属性查找方式来实现的。

把它们放在一起

首先,如图所示,一个实例是如何被构建的:

在这里插入图片描述

如何理解这个泳道图呢?

  • 水平区域是自定义的函数。
  • 实线表示函数调用。
    • 从 Metaclass.__call__到 Class.__new__的实线,表示 Metaclass.__call__将要调用 Class.__new__。
  • 虚线表示返回值。
    • Class.__new__返回 Class的实例。
    • Metaclass.__call__返回 Class.__new__的返回值(如果 Class.__new__返回的是 Class的一个实例,Metaclass.__call__还会在这个实例上调用 Class.__init__)。
  • 红圆圈中的数字记录了调用顺序。

创建一个类的流程很类似:

在这里插入图片描述

有一些需要注意的地方:

  • Metaclass.__prepare__只返回命名空间对象(如前文所述,是一个类字典 dict-like 对象)。
  • Metaclass.__new__返回 Class对象。
  • MetaMetaclass.__call__返回 Metaclass.__new__的返回值(如果 Metaclass.__new__返回的是 Metaclass的一个实例, MetaMetaclass.__call__还会在这个实例上调用 Metaclass.__init__)。

可见,元类允许您自定义一个对象生命周期的几乎每个部分。

元类是可调用的

如果再仔细看一遍前两张图,您会注意到,创建实例是通过调用 Metaclass.__call__实现的。这意味着,我们可以用任何可调用的东西作为元类。

>>> class Foo(metaclass=print):  # pointless, but illustrative
...     pass
...
Foo () {'__module__': '__main__', '__qualname__': 'Foo'}
>>> print(Foo)
None

如果您使用函数作为元类,那么子类将不能继承这个“函数元类”,而继承这个函数返回的类型。

子类继承元类

和类装饰器相比,元类的优势之一是:元类是可以被子类继承的。

这是因为 Metaclass(...)返回了一个对象,这个对象的 __class__是 Metaclass。

多个元类的限制

Python允许一个类有多个父类,每个父类又可以有不同的元类。但幸运的是,一切都必须是线性的——即继承树只能有一片叶子。

例如下述代码,是非法的Python程序,因为存在2片叶子( Meta1和 Meta2):

>>> class Meta1(type):
...     pass
...
>>> class Meta2(type):
...     pass
...
>>> class Base1(metaclass=Meta1):
...     pass
...
>>> class Base2(metaclass=Meta2):
...     pass
...
>>> class Foobar(Base1, Base2):
...     pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

这样才能正常工作(并且使用叶子做为元类):

>>> class Meta(type):
...     pass
...
>>> class SubMeta(Meta):
...     pass
...
>>> class Base1(metaclass=Meta):
...     pass
...
>>> class Base2(metaclass=SubMeta):
...     pass
...
>>> class Foobar(Base1, Base2):
...     pass
...
>>> type(Foobar)
<class '__main__.SubMeta'>

方法签名

本文还缺少一些重要的细节,比如方法的签名。让我们通过类和元类来看看这些重要的实现。

注意 **kwargs—— 用来收集其他不需要关注的关键字参数,这样就可以直接将它们传递给 class声明语句。

>>> class Meta(type):
...     @classmethod
...     def __prepare__(mcs, name, bases, **kwargs):
...         print('  Meta.__prepare__(mcs=%s, name=%r, bases=%s, **%s)' % (
...             mcs, name, bases, kwargs
...         ))
...         return {}

之前提到过,__prepare__方法返回的对象可能并不是 dict的实例。因此,您必须确保在自定义的 __new__方法中处理这种情况。

...     def __new__(mcs, name, bases, attrs, **kwargs):
...         print('  Meta.__new__(mcs=%s, name=%r, bases=%s, attrs=[%s], **%s)' % (
...             mcs, name, bases, ', '.join(attrs), kwargs
...         ))
...         return super().__new__(mcs, name, bases, attrs)

在元类中自定义 __init__并不常见,因为 __init__的作用并不大——当 __init__被调用时,类已经构建好了。元类的 __init__作用大致相当于一个类装饰器,二者的区别在于,创建子类时,元类的 __init__会运行,而子类并不会调用父类的类装饰器。

...     def __init__(cls, name, bases, attrs, **kwargs):
...         print('  Meta.__init__(cls=%s, name=%r, bases=%s, attrs=[%s], **%s)' % (
...             cls, name, bases, ', '.join(attrs), kwargs
...         ))
...         return super().__init__(name, bases, attrs)

当您创建 Class的实例时,__call__方法会被调用。

...     def __call__(cls, *args, **kwargs):
...         print('  Meta.__call__(cls=%s, args=%s, kwargs=%s)' % (
...             cls, args, kwargs
...         ))
...         return super().__call__(*args, **kwargs)
...

使用 Meta(注意 extra=1):

>>> class Class(metaclass=Meta, extra=1):
...     def __new__(cls, myarg):
...         print('  Class.__new__(cls=%s, myarg=%s)' % (
...             cls, myarg
...         ))
...         return super().__new__(cls)
...
...     def __init__(self, myarg):
...         print('  Class.__init__(self=%s, myarg=%s)' % (
...             self, myarg
...         ))
...         self.myarg = myarg
...         return super().__init__()
...
...     def __str__(self):
...         return "<instance of Class; myargs=%s>" % (
...             getattr(self, 'myarg', 'MISSING'),
...         )
  Meta.__prepare__(mcs=<class '__main__.Meta'>, name='Class', bases=(),
                   **{'extra': 1})
  Meta.__new__(mcs=<class '__main__.Meta'>, name='Class', bases=(),
               attrs=[__qualname__, __new__, __init__, __str__, __module__],
               **{'extra': 1})
  Meta.__init__(cls=<class '__main__.Class'>, name='Class', bases=(),
                attrs=[__qualname__, __new__, __init__, __str__, __module__],
                **{'extra': 1})

注意,当我们创建 Class的实例时,Meta.__call__会被调用:

>>> Class(1)
  Meta.__call__(cls=<class '__main__.Class'>, args=(1,), kwargs={})
  Class.__new__(cls=<class '__main__.Class'>, myarg=1)
  Class.__init__(self=<instance of Class; myargs=MISSING>, myarg=1)
<instance of Class; myargs=1>

尾声

现在,我已经把一切都写了出来,似乎写了很多,比我想象的还要多。但我觉得还是遗漏了什么重要的细节 😃

下一篇文章,我们将讨论这些元类理论的实际应用……

Python 中 Meta Classes详解 首先,在认识metaclass之前,你需要认识下python中的class。python中class的奇怪特性借鉴了smalltalk语言。大多数语言中,classes仅仅是用于描述怎样创建一个对象的代码端。在某种程度上说,python中的class也是这样的。 立即下载

相关推荐

深入理解Python中的元类(metaclass)

译注:这是一篇在Stack overflow上很热的帖子。提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解。他知道这肯定和自省有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理解,以及在什么情况下需要进行元编程。于是e-satis同学给出了神一般的回复,该回复获得了985点的赞同点数,更有人评论说这段回复应该加入到Python的官方文档中去。而e-satis同学本人在Stack Overflow中的声望积分也高达64271分。以下就是这篇精彩的回复(提示:非常长) 类也是对象 在理解元类之前,你需要先掌握Pyth

Python 的 metaclass

metaclass 的作用是:对新创建的类 new_class 实现一些定制 customization 功能。

drin201312的博客 2017

KEIL-MDK代码美化神器:AStyle配置全攻略(附常用参数详解)

本文详细介绍了如何在KEIL-MDK中配置和使用AStyle代码格式化工具,包括基础参数设置、高级格式控制、团队协作方案以及KEIL深度集成技巧。通过合理的AStyle配置,开发者可以显著提升代码风格一致性,优化团队协作效率,特别适合嵌入式开发项目。

weixin_30505225的博客 146

python中的metaclass

metaclass 传说metaclass在python中是个“逆天”的存在,有人认为它是“阿拉丁神灯”,无所不能;有人认为它是“潘多拉魔盒”,会蛊惑程序员去滥用,释放“恶魔”,然后悲剧就产生了。就连硅谷一线大厂要想使用metaclass都得需要特批。深入理解它的python开发人员占比不到0.1%。 它会带来好处也容易带来灾难,只有深入了解它,才能使用好它。看了一些资料,结合自己的测试,把它...

jiguanglong的博客 1万+

告别迷茫!手把手教你用Synopsys VC USB VIP搭建验证平台(附UVM分层序列实战解析)

本文详细介绍了如何使用Synopsys VC USB VIP搭建验证平台,并深入解析UVM分层序列的实战应用。通过Step-by-Step的操作指南和关键配置示例,帮助验证工程师高效集成USB VIP,掌握从环境搭建到测试用例开发的全套技能,特别适合处理复杂协议验证的挑战。

weixin_42520573的博客 554

别再用Python卷了!用Matlab的Deep Learning Toolbox快速上手U-Net图像分割(附完整数据集处理代码)

本文介绍了如何使用Matlab的Deep Learning Toolbox快速上手U-Net图像分割,包括数据准备、网络构建、训练监控和模型应用等完整流程。Matlab的高度集成工具链和图形化界面为图像分割任务提供了更快捷、直观的解决方案,特别适合研究人员和工程师快速实现原型验证。

weixin_29927965的博客 382

Python中元类(Metaclasses)详解:掌握高级编程的钥匙

除了使用默认的type元类外,我们还可以自定义元类来控制类的创建过程。在Python中,元类通常继承自type,并重写__new__方法或__init__方法来定制类的创建行为。# 自定义类创建逻辑pass在自定义元类中,__new__cls表示元类本身,name表示类名,bases表示父类元组,dct表示类的属性字典。通过重写__new__方法,我们可以完全控制类对象的创建过程。

Trb401012的博客 2290

CentOS8静默安装Oracle11.2.0.1

背景 新安装oracle,用静默安装方式就不需要安装图形界面了,省时省力。 前期准备工作与图形化安装一样,如创建用户|用户组、环境变量、内核参数、创建目录等. 可参考图形化安装,链接:https://blog.youkuaiyun.com/heroicpoem/article/details/104229369 环境 平台 版本 操作系统 centOS 8 Oracle 11gR2 1.响应文件 响应文件的内容就是图形化安装时手工设置的选项内容。 解压后,database/response/db

heroicpoem的专栏 4518

了解Python Metaclass

先以一个大牛的一段关于Python Metapgramming的著名的话来做开头: Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them kno...

北慕的博客 1211

SAP批量数据导入实战:BDC、CATT、LSMW三大工具保姆级对比教程

本文深入对比了SAP系统中三大批量数据导入工具BDC、CATT和LSMW的核心定位、适用场景与实战操作。BDC适合复杂逻辑的编程式处理,CATT适合业务用户快速录制回放,LSMW则是数据迁移项目的结构化首选。文章提供了详细的选型决策框架、性能优化技巧及常见陷阱规避指南,帮助SAP顾问和开发者高效完成数据批量维护任务。

weixin_29213525的博客 153

Yocto系列讲解[入门篇] 1 - 快速入门熟悉Yocto的构建

yocto quick start up带大家快速上手

fulinux的博客 5万+

Python中的metaclass,是时候了解一下了!

在Python中,元类(metaclass)是一种高级概念 ,用于控制类的创建过程。简单来说,元类就是“类的类”,它负责生成我们日常使用的类对象。当我们定义一个类时 ,Python解释器实际上会调用元类来创建这个类。默认情况下,所有类都使用type作为其元类,但开发者可以通过自定义元类来修改类的行为或自动添加额外的功能。我们可以利用元类和__new__方法来自动为每个类添加日志记录功能,这样每次类的实例被创建时都会记录一条消息。# 添加日志记录功能# 设置日志级别为INFO。

很多时候犯错都是在不知情的情况下发生的 616

IMX335摄像头原理图设计,已量产

从工程组织上看,IMX335 模组和 IMX415 模组属于同一类产品:核心矛盾不是外设多,而是高速图像链路、电源域和调试接口要同时兼顾。ATK-MCIMX335 这张图的结构也很直接,三路 LDO、本地 24MHz 可选时钟、4-lane MIPI 数据对和一组主板侧标准接口,构成了一张非常典型的量产摄像头子板。

不脱发的程序猿 440

Python的元类(Metaclasses)是什么?为什么要使用它?

现在,让我们定义一个简单的元类,用来打印一条消息,每当使用这个元类创建一个类时。passprint(MyClass) # 输出:在这个示例中,我们定义了一个名为Meta的元类,它继承自type。我们重写了__new__方法,这是创建类时调用的方法。当创建MyClass时,会打印一条消息,表明这个类是通过Meta元类创建的。元类是Python中一个高级且强大的特性,它们允许你控制类的创建过程。通过这篇文章,你应该对元类有了基本的了解,并且能够通过一些简单的示例来探索它们。

PythonWeb实践 960

Python 爬虫教程:美食网站 + 社交平台餐馆评论抓取(评分提取 + 情感分析)

在当今数字化时代,数据无处不在,而爬虫技术则是获取数据的强大工具之一。无论是市场调研、学术研究还是个人兴趣探索,爬虫都能帮助我们从海量的网络信息中提取有价值的数据。本文将通过一个实战案例,带领大家学习如何使用 Python 爬虫技术抓取美食网站和社交平台上的餐馆评论,并进行评分提取与情感分析。通过这个项目,你将掌握爬虫的基本原理、数据解析、以及如何结合情感分析技术来挖掘数据背后的洞察。

u014481728的博客 311

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Python “黑魔法” 之 Meta Classes

首发于 我的博客 转载请注明出处 接触过 Django 的同学都应该十分熟悉它的 ORM 系统。对于 python 新手而言,这是一项几乎可以被称作“黑科技”的特性:只要你在models.py中随便定义一个Model的子类,Django 便可以: 获取它的字段定义,并转换成表结构 读取Meta内部类,并转化成相应的配置信息。对于特殊的M...

weixin_34336292的博客 204

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Python 元类 metaclass 详解

Python 元类 metaclass 详解

kindtester的博客 1251

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

2高级编程-面对对象的深度问题-对类进行修改和控制-metaclass-全栈式开发18

一、模块的简介和创建 模块的定义 模块化指将一个完整的程序分解成一个个的小模块,通过将模块组合,来搭建出一个完整的程序 模块化的优点 方便开发 方便维护 模块可以复用 分成一个一个小文件,方便查询修改 模块的创建 在Python当中一个py文件就是一个模块 二、模块的使用 模块的分两步:导包和访问 模块的导包 在一个模块中引入外部模块 import 模块名(模块名就是py文件名) 可以引入同一个模块多次,但后面的会把前面的覆盖掉 import 模块名 as 模块别名 from 模块名 impo

weixin_43761516的博客 397

【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 分析使用 MetaClass 进行方法注入前后 mateClass 类型变化 )

一、分析使用 MetaClass 进行方法注入前后 mateClass 类型变化、 二、完整代码示例、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1389

[Python]五分钟理解元类(Metaclasses)

<p class="MsoNormal" align="center" style="margin-top:7.5pt;margin-right:0cm;margin-bottom:7.5pt;margin-left:0cm;text-align:center;mso-pagination:widow-orphan;mso-outline-level:1"><span style="fon

赖勇浩的编程私伙局 2万+

理解python metaclass

原文地址:https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/现存的文章没有说明白metaclass是如何在Python中工作的,所以在这里我给出我的理解。metaclass在python中永远是一个争议的话题。许多开发者避免使用它们,而我认为这很大程度上是有任意的工作流程和查找规则引起的,它们没能很好的解释。同时...

月如钩 1万+

Python 元类 - Metaclasses

1 Python 元类 - Metaclasses 2 3 默认情况下儿, classes 是有 type() 构造的. 4 类的结构体在一个新的 namespace 被执行, 类的名字 class name 绑定(bound locally)到 5 type(name, bases, namespace) 的结果上. 6 然而, 类的构造过程可以用户定义...

weixin_30732825的博客 171

深入理解Python的元类

类也是对象 在理解Python的元类之前,你需要掌握Python的类相关的知识。Python的类,有一个借鉴自Smalltalk语言的特殊的概念。 在大多数编程语言中,类就是一组描述如何生成对象的一段代码块。在Python中这一点也是成立的。 但是,在Python中类还远不止这些功能,类也是对象,没错,对象。 只要你使用关键字class修改,Python解释器会执行这代码代码,并...

python学习者的博客 927

Python中的Classes和Metaclasses详解

这篇文章主要介绍了Python中的Classes和Metaclasses详解,属于基础知识中类与对象的概念部分的深入,需要的朋友可以参考下 类和对象 类和函数一样都是Python中的对象。当一个类定义完成之后,Python将创建一个“类对象”并将其赋值给一个同名变量。类是type类型的对象(是不是有点拗口?)。 类对象是可调用的(callable,实现了 __call__方法),并且

huobanjishijian的专栏 719
上一篇: 深刻理解Python中的元类(metaclass)
下一篇: 函数式编程实战教程(Python版)
kkknd007
博客等级 码龄16年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值