Python面试常用的高级用法,怎么动态创建类?

简介:

Python面试常用的高级用法,怎么动态创建类?

本文始发于个人公众号:TechFlow,原创不易,求个关注

今天是Python专题的第16篇文章,今天我们来聊聊Python当中的元类。

元类是Python当中的高级用法,如果你之前从来没见过这个术语或者是没听说过这个概念,这是非常正常的,因为一方面它的使用频率不高,另外一方面就是它相对不太容易理解。以至于很多Python开发者都理解得不是很深入,导致了市面上相关的资料也并不太多。我也是读了一些大牛的代码才开启了这扇新世界的大门。

一切都是对象
我们之前的时候曾经介绍过,在Python当中一切都是对象,注意,是一切都是对象。我们都知道对象是类实例化之后的结果,可以简单地将类和对象类比成模具和成品的关系。模具是类,而根据模具做出来的产品是对象。

这个比喻思想比较接近,但是不完美。因为实际当中一个模具可以做出多个产品,一个产品只有一个模具。但编程语言当中不同,由于类之间可以继承以及多继承,也就是说一个对象可以对应多个类。所以这个比喻不是特别合适,但是类和对象的关系是没错的。

但是这就有了一个问题,既然Python当中一切都是对象,那么是不是说类其实也是一个对象呢?也就是说一个模具其实也是另外一个模具的产品?同样,这个模具的模具其实也是另外一个模具的产品,那么我们一直追问下去会怎么样呢?

很简单,我们做个实验就知道了,我们可以用_class__关键字来查看一个变量的类型,那么我们反复调用就可以查看其中的关系了:

从上面的图中我们可以发现,num是int类型的变量。我们继续查看int这个类型的类型,得到了type类型。而当我们去查看type的类型的时候,会发现我们得到的还是一个type的类型。

所以我们可以明白了,type是Python中用来创建所有类的元类,是所有模具的模具。在Python当中,我们把一个类的类叫做元类(metaclass)。所以type就是Python当中内置的元类,我们也可以自己创建我们需要的元类。通过元类,我们创建的对象也是一个类,而不是一个实例。

动态创建类
理解了type是一切类基础之后,再来看动态类就简单了。动态类是动态语言最大的特性之一,作为典型的动态语言,Python自然也是支持类型的动态创建的。

在Python当中,创建动态类型的一种方式就是通过type关键字。说起来有些意想不到,type函数不是用来查询对象所属的类型的吗,怎么还可以创建类呢?

这其实是type的另外一种用法,作为元类来创建一个类。在这种用法,type函数接收3个参数,分别是类型的名称,父类的元组,以及一个字典。除了第一个参数之外,后面两个参数都可以为空。比如我们来看一个例子:

注意,type返回的结果是一个类,而不是一个实例。所以我们还可以通过它创建实例:

hello = Hello()
这样创建出来的是最简单的空类,它什么也没有,和下面的代码等价。

class Hello:

pass

我们也可以在type的参数当中为这个类填充属性和方法:

def hello_world(self):

print('hello')

Hello = type('Hello', (), {'hello':hello_world, 'num': 3})
这样我们就为Hello这个类创建了一个方法叫做hello,一个属性num等于3。我们可以来调用一下试试:

也就是说我们可以使用type来根据我们的需要自行定义类,只不过type既可以获取对象的类型又可以创建新的类,看起来可能觉得有些不太直观,但是其实这也是说得通的。我们在Python当中通过调用str创建一个string对象,通过int来创建一个integer对象,那么通过type则是创建一个类的对象。

实现继承
我们之前说了,当我们使用type来创建类的时候,还可以传入父类的元组从而实现类的继承。

比如我们再创建一个叫做World的类继承刚才通过type创建出来的Hello类,然后在为它加上额外的函数:

def say_world(self):

print('World')

World = type('World', (Hello, ), {'world': say_world})
注意这里传入第二个参数是父类的元组,既然是元组,那么当元素只有一个的时候,需要加上逗号,表示这是一个元组。这样创建出来的类和我们通过class定义的静态类效果是一样的:

也就是说,我们可以先把函数实现,然后再根据任务的需要把这些函数组装成新的类。显然,这和传统的C++以及Java这些静态类型的语言相比,要灵活得多。

总结
我们固然可以通过type来创建动态创建类,但是从上面的使用过程也应该看得出来,这样使用起来并不太方便,并且很多进阶的功能很难实现。举个简单的例子,比如我们想要动态地为一个已有的类添加一些动态的方法,生成新的类。我们使用type就很难实现。type也的确不是Python元类的主要运用,metaclass才是王道,但由于篇幅限制,这部分将放在下一篇文章当中。

当然,元类是一个非常高级的用法,以至于Python的创始人说99%的Python程序员并不需要用到它。所以如果你觉得理解起来非常费劲的话也没有关系,知道这么个概念就可以了。

原文地址https://www.cnblogs.com/techflow/p/13048318.html

相关文章
|
4月前
|
机器学习/深度学习 PyTorch 算法框架/工具
python torch基础用法
本教程系统讲解PyTorch基础,涵盖张量操作、自动求导、神经网络构建、训练流程、GPU加速及模型保存等核心内容,结合代码实例帮助初学者快速掌握深度学习开发基础,是入门PyTorch的实用指南。
689 6
|
5月前
|
缓存 供应链 芯片
电子元件类商品 item_get - 商品详情接口深度分析及 Python 实现
电子元件商品接口需精准返回型号参数、规格属性、认证及库存等专业数据,支持供应链管理与采购决策。本文详解其接口特性、数据结构与Python实现方案。
|
6月前
|
Go 调度 Python
Golang协程和Python协程用法上的那些“不一样”
本文对比了 Python 和 Go 语言中协程的区别,重点分析了调度机制和执行方式的不同。Go 的协程(goroutine)由运行时自动调度,启动后立即执行;而 Python 协程需通过 await 显式调度,依赖事件循环。文中通过代码示例展示了两种协程的实际运行效果。
295 7
|
9月前
|
人工智能 数据库连接 API
掌握Python的高级用法:技巧、技术和实用性示例
本文分享了Python的高级用法,包括生成器、装饰器、上下文管理器、元类和并发编程等。生成器通过`yield`实现懒加载序列;装饰器用于增强函数功能,如添加日志或性能分析;上下文管理器借助`with`语句管理资源;元类动态定制类行为;并发编程利用`threading`和`asyncio`库提升任务执行效率。掌握这些高级概念可优化代码质量,解决复杂问题,提高程序性能与可维护性。
216 6
|
10月前
|
Python
Python教程:os 与 sys 模块详细用法
os 模块用于与操作系统交互,主要涉及夹操作、路径操作和其他操作。例如,`os.rename()` 重命名文件,`os.mkdir()` 创建文件夹,`os.path.abspath()` 获取文件绝对路径等。sys 模块则用于与 Python 解释器交互,常用功能如 `sys.path` 查看模块搜索路径,`sys.platform` 检测操作系统等。这些模块提供了丰富的工具,便于开发中处理系统和文件相关任务。
466 14
|
测试技术 Python
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
672 31
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
|
10月前
|
人工智能 Python
[oeasy]python083_类_对象_成员方法_method_函数_function_isinstance
本文介绍了Python中类、对象、成员方法及函数的概念。通过超市商品分类的例子,形象地解释了“类型”的概念,如整型(int)和字符串(str)是两种不同的数据类型。整型对象支持数字求和,字符串对象支持拼接。使用`isinstance`函数可以判断对象是否属于特定类型,例如判断变量是否为整型。此外,还探讨了面向对象编程(OOP)与面向过程编程的区别,并简要介绍了`type`和`help`函数的用法。最后总结指出,不同类型的对象有不同的运算和方法,如字符串有`find`和`index`方法,而整型没有。更多内容可参考文末提供的蓝桥、GitHub和Gitee链接。
265 11
|
11月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
11月前
|
存储 C语言 Python
[oeasy]python077_int类型怎么用_整数运算_integer_进制转化_int类
本文主要讲解了Python中`int`类型的应用与特性。首先回顾了`int`词根的溯源,探讨了整型变量的概念及命名规则(如匈牙利命名法)。接着分析了整型变量在内存中的存储位置和地址,并通过`type()`和`id()`函数验证其类型和地址。还介绍了整型变量的运算功能,以及如何通过`int()`函数将字符串转化为整数,支持不同进制间的转换(如二进制转十进制)。此外,文章提及了关键字`del`的使用场景,对比了Python与C语言中`int`的区别,并总结了整型与字符串类型的差异,为后续深入学习奠定基础。
277 1
|
11月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。

推荐镜像

更多