zoukankan      html  css  js  c++  java
  • Python面试常用的高级用法,怎么动态创建类?

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

    很多人学习python,不知道从何学起。
    很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
    很多已经做案例的人,却不知道如何去学习更加高深的知识。
    那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
    QQ群:1097524789

    一切都是对象

    我们之前的时候曾经介绍过,在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程序员并不需要用到它 。所以如果你觉得理解起来非常费劲的话也没有关系,知道这么个概念就可以了。

  • 相关阅读:
    linux系统分析工具续-SystemTap和火焰图(Flame Graph)
    如何使用strace+pstack利器分析程序性能
    MySQL数据类型-decimal详解
    服务器端数据合法性验证:签名sign和口令token原理
    linux系统下php通过php_oci8扩展连接oracle数据库 Nginx
    redis开启远程访问
    cURL函数库错误码说明之PHP curl_errno函数
    权限控制相关模块
    otool
    路由器
  • 原文地址:https://www.cnblogs.com/shann001/p/13049201.html
Copyright © 2011-2022 走看看