加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python零基础入门之——Python 中的元编程!Python真的好牛逼!

发布时间:2020-12-17 01:17:38 所属栏目:Python 来源:网络整理
导读:p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,93,93);font-family:helvetica,Arial,'Hiragino Sans GB','Microsoft YaHei',simsun;background-color:rgb(255,255,255);"就像元数据是有关数据的数据一样,元编程就是编写用于操纵

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,93,93);font-family:helvetica,Arial,'Hiragino Sans GB','Microsoft YaHei',simsun;background-color:rgb(255,255,255);">就像元数据是有关数据的数据一样,元编程就是编写用于操纵程序的某些程序。人们普遍认为,元程序就是生成其他程序的某些程序,但范式更加广泛。所有旨在自我读取、分析、转换或修改的程序都是元编程的范例。例如:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/1527491017193e8b020317a

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,153,153);font-family:helvetica,255);">请点击此处输入图片描述

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/1527491036473ec7c10eb66

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/15274910638585abf148e5d

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/15274911055822733e2fd35

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">发现了吗?事实证明,一开始的说法(一切都是对象)并不完全正确。下面是更准确的说法:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">除 type 之外,Python 中的一切都是对象,它们要么是类的实例,要么是元类的实例。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">验证这一点:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/15274911285111e2a9447ab

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">定义了某个类后会发生什么情况?

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">我们首先回顾下已知的内容。Python 程序的基本构建块是:

<ul class="list-paddingleft-2" style="margin-bottom:0px;width:747.641px;padding-left:30px;color:rgb(93,255);"><li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">语句

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">函数

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">类

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/152749116275008fe05b7a3

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/1527491181239a877ea4294

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">以下是每次遇到关键字类时发生的情况:

<ul class="list-paddingleft-2" style="margin-bottom:0px;width:747.641px;padding-left:30px;color:rgb(93,255);"><li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">类的主体(语句和函数)被隔离。

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">创建类的名称空间字典(但尚未填充)。

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">先执行类的主体,然后使用所有属性、定义的方法以及与类有关的其他一些有用信息来填充名称空间字典。

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">在基类或要创建的类的元类挂钩(稍后解释)中确定元类。

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">然后,通过类的名称、基类和属性调用元类,对其进行实例化。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/152749119375720ccf1eb37

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/152749124830617860801a5

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/1527491257876527b32dd7f

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">请点击此处输入图片描述

<ul class="list-paddingleft-2" style="margin-bottom:0px;width:747.641px;padding-left:30px;color:rgb(93,255);"><li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">分配给某个变量

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">复制

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">作为参数传递给其他函数

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">前面的语法实际等同于:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/1527491272028ca52d11877

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">我们假设自己有一个从 URL 访存已提取数据的函数。我们从中访存数据的服务器具备调节机制,如果它检测到在相同时间间隔内从某个 IP 地址传入大量请求,就会进行调节。所以,为了让提取器像人类一样,我们愿意等待随机长度的时间,然后再提交请求以欺骗服务器。 能否使装饰器也做到这样?我们来看一下:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/15274913622797d4b27b7b2

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/1527491391495be7b5611cd

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/1527491404083b320f85e20

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/1527491415935a1b26b7b89

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/152749147753708f9952bd6

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/15274915080404567c9450c

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/15274915168688a57563878

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">它已运行!现在,您已了解了如何在 Python 中编写和使用元类。我们再来探究一下这有何用途。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">在 Python 中使用元类

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">您可以使用元类对属性、方法及其值执行不同的准则。前面例子(使用 snake_case)的类似示例包括:

<ul class="list-paddingleft-2" style="margin-bottom:0px;width:747.641px;padding-left:30px;color:rgb(93,255);"><li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">值的域限制

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">隐式转换自定义类的值(您可能希望向用户隐藏编写类的所有这些复杂方面)

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">执行不同的命名约定和样式准则(比如,“每种方法都应有一个文档字符串”)

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">向类添加新的属性

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">在类定义本身中定义所有这种逻辑时使用元类,主要原因就是为了避免在整个代码库中出现重复代码。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">元类的实际使用

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">因为在子类中会继承元类,所以元类解决了代码冗余(不要重复自己 — DRY)这一实际问题。 通常情况下,在生成类对象的同时,通过执行额外操作或添加额外代码,元类也可以帮助提取有关类创建的复杂逻辑。元类的一些实际用例包括:

<ul class="list-paddingleft-2" style="margin-bottom:0px;width:747.641px;padding-left:30px;color:rgb(93,255);"><li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">抽象基类

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">类的注册

<li style="clear:both;"><p style="margin-top:5px;margin-bottom:5px;">在库和框架中创建 API

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">我们来具体看一下每个示例。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">抽象基类

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">抽象基类是只能被继承而不会被实例化的类。Python 具有以下内容:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/15274915400383313c6a2ee

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">请注意,我们没有实现抽象方法。我们来看下如果尝试实例化?<code style="line-height:1.5em;padding:10px;margin:15px 0px;background:rgb(240,240,240);font-family:monaco,Consolas,'Liberation Mono',Courier,monospace;white-space:pre;">Truck?类的对象会发生什么情况:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/1527491555334e8a8c4eb1d

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">

pgc-image/1527491570050765bfe1ec4

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">现在,根据文件格式,我们很容易就知道要使用哪个处理程序类。一般来说,无论何时需要维护存储类特征的某种数据结构,都可以使用元类。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">创建 API

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">由于元类能够防止子类中的逻辑冗余,能够隐藏用户无需知道的自定义类创建逻辑,因此元类在框架和库中得到广泛应用。这为减少样板和拥有更出色的 API 创造了一些值得注意的机会。例如,思考一下 Django ORM 的这个使用片段:

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">

pgc-image/1527491595464a3a5d10555

<p class="pgc-img-caption" style="margin-top:-6px;margin-bottom:1em;text-align:center;line-height:1.5;color:rgb(153,255);">作为创建车辆模型的用户,我们只需从 models.Model 类继承,然后编写一些高级语句。其余工作(比如创建数据库挂钩,提出无效值错误,返回?<code style="line-height:1.5em;padding:10px;margin:15px 0px;background:rgb(240,monospace;white-space:pre;">int?类型而不是 models.IntegerField)则由 model.Models 类以及它使用的元类在后台完成。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">总结

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">在本教程中,您了解了 Python 中的实例、类以及元类之间的关系。您学习了元编程知识,这是一种操纵代码的方法。我们讨论了函数装饰器和类装饰器,二者是将自定义行为注入到类和方法中的一种方式。然后,我们通过使 Python 的默认 type 元类子类化,实现了自定义元类。最后,我们介绍了元类的一些实际用例。是否使用元类这个问题在网上饱受争议,但是现在,对于某种问题是否利用元编程才能更好地解决,您应该可以更轻松地展开分析并得出答案。

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);">欢迎关注我的博客或者公众号:https://home.cnblogs.com/u/Python1234/ ? ? ? ? ?Python学习交流

<p style="margin-top:1em;margin-bottom:1em;line-height:1.5;color:rgb(93,255);"><span style="color:rgb(37,53,69);font-family:'PingFang SC',SourceHanSansCN,'Helvetica Neue',Helvetica,'DINAlternate-Bold';font-size:17px;line-height:30px;background-color:rgb(255,255);">欢迎加入我的千人交流答疑群:125240963

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读