摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类。

Python元类设置类的行为和规则。元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一。通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类。本文介绍以下概念:

    • 什么是Python元类?
    • Python中的类和对象
    • Python中的动态类
    • Python元类如何工作?
      • 类型类
      • Python中的自定义元类
    • 装饰器vs元类

什么是Python元类?

Python元类是与Python的面向对象编程概念相关的高级功能之一。它确定类的行为,并进一步帮助其修改。

用Python创建的每个类都有一个基础的Metaclass。因此,在创建类时,您将间接使用元类。它隐式发生,您无需指定任何内容。

与元编程相关联的元类决定了程序对其自身进行操作的能力。 学习元类可能看起来很复杂,但是让我们先从一些类和对象的概念入手,以便于理解。

Python中的类和对象

类是一个蓝图,是具有对象的逻辑实体。 一个简单的类在声明时没有分配任何内存,它是在创建一个类的实例时发生的。

通过创建的对象,可以访问该类。该类仅用作模板。对象的属性本质上意味着我们可以在运行时与它进行交互,传递诸如变量之类的参数,进行存储,修改,也可以与它进行交互。

可以使用__class__属性检查对象的类。让我们看一个简单的例子:

class Demo: 
       pass       
#This is a class named demo
 test=Demo()
print(test.__class__)  #shows class of obj
print(type(test))  #alternate method

Output:

Python大量处理类和对象的概念,并允许轻松,顺利地进行应用程序开发。但是,什么使Python与Java和C这样的语言不同呢?Python中的所有内容都可以定义为具有属性和方法的对象。 主题演讲是Python中的类不过是更大类的另一个对象。

类为对象定义规则。同样,元类负责为类分配行为。我们已经知道,类是对象,就像每个对象都有一个实例一样,类是元类的实例。

但是也有像Ruby和Objective-C这样的语言也支持元类。那么,是什么使Python Metaclass更好,为什么还要学习它呢?答案是Python中的动态类。让我们仔细看看。

Python中的动态类

Python是一种动态编程语言,并允许在运行时创建类。与C ++等其他语言不同,后者仅允许在编译时创建类。在灵活性方面,Python优于其他静态类型的语言。

动态和静态类型语言之间的差异并不大, 但是在Python中,它由于提供元编程而变得更加有用。

但是,如果我告诉您还有另一个关键功能将Python与其他编程语言区分开呢?

诸如Java或C ++之类的语言具有float,char,int等数据类型,而Python将每个变量视为对象。每个对象都属于一个类,例如int类或str类。您可以使用称为type()的内置函数来简单地检查任何变量的类。

number = 10993 print("Type associated is:", type(number))
name = "Aishwarya" print("Type associated is:", type(name))

Output:

Type associated is:

Type associated is:

现在,您了解了Python中的所有内容都有与之关联的类型。在下一个主题中,我们将尝试了解元类实际上是如何工作的。

Python元类如何工作?

每当创建一个类时,都会调用默认的Metaclass类型。 元类包含名称,基类集以及与该类关联的属性等信息。因此,在实例化一个类时,将调用带有这些参数的类。可以通过两种方法创建元类:

  1. 类型类
  2. 自定义元类

让我们继续输入class以及如何创建class。

类型类

Python有一个称为type的内置元类。与Java或C不同,那里有主要的数据类型。Python中的每个变量或对象都有一个与之关联的类。Python使用幕后的Type类创建所有类。在上一个主题中,我们看到了如何使用type()检查对象的。让我们举一个例子,说明如何通过创建一个简单的类来定义新类型。

class Edureka():
obj = Edureka()
 
print(type(obj))

Output:

print(type(Edureka))

Output:

在上面的代码中,我们有一个名为Edureka的类,以及一个关联的对象。我们通过简单地在该类型之后创建一个名为自身的类,创建了一个名为Edureka的新类型。在第二个代码中,当我们检查Edureka类的类型时,其结果为“类型”。

因此,除非另有定义,否则元类使用类型类来创建所有其他类。我们可以通过两种方法访问Type类:

当我们通过类型类传递参数时,它使用以下语法。

type(__name__, __base__, attributes)
  • 名称是一个字符串,并带有类名
  • 该基础是一个元组,可帮助创建子类
  • 属性是字典,并分配键值对

由于Python中的类的行为与对象相似,因此可以用相同的方式更改其行为。我们可以在类内添加或删除方法,类似于对对象的处理方式。

现在您已经知道Metaclass在Python中创建了所有其他类,并使用类型class定义了它们的行为。但是,您一定想知道,我们还有其他方法可以创建元类吗?因此,让我们看看如何创建一个自定义的元类。

Python中的自定义元类

现在我们知道并理解类型类如何工作。现在该学习如何创建自定义元类了。我们可以通过执行动作或代码注入来修改类的工作。为此,我们可以在创建类定义时将Metaclass作为关键字传递。另外,我们可以通过简单地继承通过此Metaclass关键字实例化的类来实现此目的。

在创建新类时,Python查找__metaclass__ 关键字。以防万一,如果不存在。它遵循类型类层次结构。

Python在命名空间中执行所有字典后,将调用类型对象,后者创建类的对象。我们可以使用两种方法来创建自定义元类。

class EduFirst(type):
def __new__(cls, name, base_cls, dict):
pass class EduSecond(type):
def __init__(self, name, base_cls, dict):
pass

让我详细解释这两种方法:

  1. __new __(): 当用户要在类创建之前定义元组字典时使用。它返回一个类的实例,并且很容易覆盖/管理对象流。
  2. __init __():在创建对象并对其进行初始化之后调用它。

Python中的__call__是什么?

在正式的Python文档中,__call__方法可用于定义自定义元类。同样,当调用类定义自定义行为时,我们可以覆盖__prepare__之类的其他方法。

就像类如何像创建对象的模板一样,元类也像类创建模板一样。因此,元类也称为类工厂。

请参见下一个示例:

class Meta(type):
def __init__(cls, name, base, dct):
cls.attribute = 200 class Test(metaclass = Meta):
pass
Test.attribute

Output: 200

元类允许自定义类。还有多种其他有效且简单得多的方法可以通过这些方法实现相同的输出。这样的例子之一就是使用装饰器。

装饰器vs元类

Decorator是Python的一项流行功能,它允许您向代码中添加更多功能。装饰器是可调用的对象,可帮助修改现有的类甚至函数。在编译期间,部分代码将调用并修改另一部分。此过程也称为元编程。

def decorator(cls): class NewClass(cls):
attribute = 200 return NewClass
@decorator
Class Test1:
 pass
@decorator
 
Class Test2:
 pass
Test1.attribute
 
Test2.attribute

Output: 200

Python中的Decorator是一个非常有用且功能强大的工具,可帮助您更改函数的行为,而无需实际更改任何代码。 当您要在调试时修改程序的一部分而不是重写函数或更改整个程序时,这非常方便。取而代之的是,您只需编写一个单行装饰器,其余的就由它来处理。

本文分享自华为云社区《如何创建您的第一个Python元类?》,原文作者:Yuchuan。


点击关注,第一时间了解华为云新鲜技术~

标签:Python元类

Python进阶丨如何创建你的第一个Python元类?的更多相关文章

  1. 用python做youtube自动化下载器 代码

    目录项目地址思路流程1. posti. 先把post中的headers格式化ii.然后把参数也格式化iii. 最后再执行requests库的post请求iv. 封装成一个函数2. 调用解密函数i. 分析ii. 先取出js部分iii. 取第一个解密函数作为我们用的解密函数iv. 用execjs执行1.......

  2. python基于opencv实现人脸识别

    将opencv中haarcascade_frontalface_default.xml文件下载到本地,我们调用它辅助进行人脸识别。识别图像中的人脸#coding:utf-8import cv2 as cv# 读取原始图像img = cv.imread('face.png')# 调用熟悉的人脸分类器 ......

  3. 详解用 python-docx 创建浮动图片

    相信大家对python-docx这个常用的操作docx文档的库都不陌生,它支持以内联形状(Inline Shape)的形式插入图片,即图片和文本之间没有重叠,遵循流动版式(flow layout)。但是,截至最新的0.8.10版本,python-docx尚不支持插入浮动图片(floating pic......

  4. python中openpyxl和xlsxwriter对Excel的操作方法

    前几天,项目中有个小需求:提供Excel的上传下载功能,使用模块:openpyxl 和 xlsxwriter,这里简单记录一下。1.简介Python中操作Excel的库非常多,为开发者提供了多种选择,如:xlrd、 xlwt、xlutils、xlwings、pandas、 win32com、open......

  5. opencv python 对指针仪表读数识别的两种方式

    我尝试了两种方式用opencv 对指针仪表进行读数识别,1. 先模板匹配,然后边缘检测 + 霍夫直线2. 按轮廓大小过滤,然后边缘检测 + 霍夫直线两种方式对光线都非常敏感其中第一种的应用范围更广,背景复杂一点也能识别到个人比较喜欢这种方式第二种的限制多一点,对背景、光线条件要求比较高对于固定位置,......

  6. Python字符串对齐、删除字符串不需要的内容以及格式化打印字符

    删除字符串中不需要的内容1、strip()方法strip:默认是去掉首尾的空白字符,但是也可以指定其他字符;lstrip:只去掉左边的;rstrip:只去掉右边的;print('+++apple '.strip()) # '+++apple'print('+++apple '.lstrip('+')......

  7. python中lower函数实现方法及用法讲解

    之前小编介绍过python中将字符串小写字符转为大写的upper函数的使用方法(upper函数)。有将小写转为大写的需要,那也有将大写转为小写的情况。本文主要介绍在python中可以将字符串大写自摸转换为小写字母的lower函数。1、lower()转换字符串中所有大写字符为小写2、语法str.low......

  8. 【python接口自动化】- 正则用例参数化

    我们在做接口自动化的时候,处理接口依赖的相关数据时,通常会使用正则表达式来进行提取相关的数据。正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(Regular Expression,在代码中常简写为regex、regexp或RE) 。它是一个特殊的字符序列,它能帮助你方便的......

  9. 通过python-pptx模块操作ppt文件的方法

    ppt通过其精美的可视化技巧以及良好的演示效果,成为了职场人士的必备技能。ppt的设计是一门大学问,无论是设计技巧,还是操作方法,都衍生出了专门的课程。本文主要介绍python操作ppt的技巧,编程的优势在于处理速度,对于高大上的ppt设计,还是需要"以人为本", 所以该模块的使......

  10. Python 实现进度条的六种方式

    一、普通进度条示例代码import sysimport timedef progress_bar():for i in range(1, 101):print("\r", end="")print("Download progress: {}%: &......

随机推荐

  1. Java中EasyPoi导出复杂合并单元格的方法

    前言:上星期做了一个Excel的单元格合并,用的是EasyPoi,我之前合并单元格都是原生的,第一次使用EasyPoi合并也不太熟悉,看着网上自己套用,使用后发现比原生的方便些,贡献一下,也给其他用到合并而且用的是EasyPoi的小伙伴节省下时间。导出模板:坐标:版本号,自己来定,可以去官网查看:E......

  2. 【python接口自动化】- 正则用例参数化

    我们在做接口自动化的时候,处理接口依赖的相关数据时,通常会使用正则表达式来进行提取相关的数据。正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(Regular Expression,在代码中常简写为regex、regexp或RE) 。它是一个特殊的字符序列,它能帮助你方便的......

  3. .NET 5 程序高级调试-WinDbg

    上周和大家分享了.NET 5开源工作流框架elsa,程序跑起来后,想看一下后台线程的执行情况。抓了个进程Dump后,使用WinDbg调试,加载SOS调试器扩展,结果无法正常使用了:0:000> .loadby sos clrUnable to find module 'clr'这引起了个人的兴......

  4. 解决python 读取npy文件太大不能完全显示的问题

    python读取npy文件时,太大不能完全显示,其解决方法当用python读取npy文件时,会遇到npy文件太大,用print函数打印时不能完全显示,如以下情况:解决办法添加一行代码:np.set_printoptions(threshold = 1e6),其中threshold表示输出数组的元素数......

  5. Android如何实现动态滚动波形图(心电图)功能

    一、前言最近涉及的某个医疗相关的业务,传感器数据传递上来需要实现示波器的效果,心电图的效果,目前交付效果还算理想,于是封装了一下,方便自己以后使用,也给大家分享一下二、效果图图一是心电图效果,图二是一个滚动的波形图三、功能实现(一)绘制背景网格为了让他看上去像示波器上的数据,我们先绘制一层网格背景,......

  6. python中yield的用法详解

    首先我要吐槽一下,看程序的过程中遇见了yield这个关键字,然后百度的时候,发现没有一个能简单的让我懂的,讲起来真TM的都是头头是道,什么参数,什么传递的,还口口声声说自己的教程是最简单的,最浅显易懂的,我就想问没有有考虑过读者的感受。接下来是正题:首先,如果你还没有对yield有个初步分认识,那么......

  7. JVM必不可少的知识

    1.Java垃圾回收机制对象被判断为垃圾的标准:没有被其他对象引用2.判断对象是否可被回收(1)引用计数算法判断对象的引用数量通过判断对象的引用数量来决定对象是否可以被回收每个对象实例都有一个引用计数器,被引用则+1,完成引用则-1任何引用计数为0的对象实例可以被当作垃圾回收优点:执行效率高,程序执......

  8. 如何讲清楚 Java 面向对象的问题与知识?(类与对象,封装,继承,多态,接口,内部类...)

    如何讲清楚 Java 面向对象的问题与知识?(类与对象,封装,继承,多态,接口,内部类...)写在最前面这个项目是从20年末就立好的 flag,经过几年的学习,回过头再去看很多知识点又有新的理解。所以趁着找实习的准备,结合以前的学习储备,创建一个主要针对应届生和初学者的 Java 开源知识项目,专注......

  9. Java 容器系列总结

    为什么要使用集合当我们需要保存一组类型相同的数据的时候,我们应该是用一个容器来保存,这个容器就是数组,但是,使用数组存储对象具有一定的弊端, 因为我们在实际开发中,存储的数据的类型是多种多样的,于是,就出现了“集合”,集合同样也是用来存储多个数据的。数组的缺点是一旦声明之后,长度就不可变了;同时,声......

  10. Vue使用Ref跨层级获取组件实例

    目录Vue使用Ref跨层级获取组件实例示例介绍文档目录结构安装vue-ref根组件自定义方法[使用provide和inject]分别说明各个页面结果Vue使用Ref跨层级获取组件实例示例介绍在开发过程中,我们难免会使用到跨层级的ref实例获取,大部分情况下,我们都可以通过组件自身的parent或者c......