专栏首页极客起源Python编程思想(29):使用type()函数定义类

Python编程思想(29):使用type()函数定义类

----------支持作者请转发本文-----------

李宁老师已经在「极客起源」 微信公众号推出《Python编程思想》电子书,囊括了Python的核心技术,以及Python的主要函数库的使用方法。读者可以在「极客起源」 公众号中输入 160442 开始学习。

-----------正文-----------

在Python语言中使用 type函数可以查看变量的数据类型,但如果想使用 type直接查看某个类的类型型呢?先看如下程序:

示例代码:type_demo. py

class MyClass:
pass
my = MyClass()
# 查看变量my的类型
print(type(my)) # <class '__main__.MyClass'>
# 查看MyClass类本身的类型
print(type(MyClass)) # <class 'type'>

运行这段代码,会在Console中输出如下内容:

<class '__main__.MyClass'>
<class 'type'>

从上面的输出结果可以看到,MyClass类本身的类型是type。那么怎样理解MyClass类的类型是type呢?

从 Python解释器的角度来看,当程序使用 class定义MyClass类时,也可理解为定义了一个特殊的对象(type类的对象),并将该对象赋值给MyClass变量。因此,程序使用 class定义的所有类都是type类的实例。

实际上 Python完全允许使用 type函数(相当于type类的构造器函数)来创建type对象,又由于type类的实例就是类,因此,Python可以使用 type函数来动态创建类,代码如下:

示例代码: type_ class. py

def run(self):
print('run函数')
# 使用type()定义Person类
Person = type('Person', (object,), dict(run=run, age=12))
# 创建Person对象
p = Person()
# 分别查看p和Person的类型
print(type(p))
print(type(Person))
p.run()
print(Person.age)

在这段代码中使用type函数定义了一个Person类。在使用type()函数定义类时可指定如下3个参数:

参数1:创建的类名;

参数2:该类继承的父类集合。由于 Python支持多继承,因此该参数使用元组指定它的多个父类。即使实际只有一个父类,也需要使用元组指定父类(必须要多一个逗号,否则会抛出下面的异常);

TypeError: type.__new__() argument 2 must be tuple, not type

参数3:该参数是一个字典类型的值,表示该类绑定的类变量和方法。其中字典的key就是类变量或方法,如果字典的 value是普通值,那就代表类变量;如果字典的 value是函数,则代表方法;

由此可见,这段代码中定义的Person类的父类是object类,还为该类定义了一个run()方法和一个age类变量。运行这段代码,会输出如下的结果:

<class '__main__.Person'>
<class 'type'>
run函数
12

从上面的输出结果可以看出,使用 type()函数定义的类与直接使用 class定义的类并没有任何区别。事实上, Python解释器在执行使用 class定义的类时,其实依然是使用 type函数来创建类的。因此,无论通过哪种方式定义类,程序最终都是创建一个type的实例。

本文分享自微信公众号 - 极客起源(geekculture),作者:geekori

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python从菜鸟到高手(2):清空Python控制台

    执行python命令会进入Python控制台。在Python控制台中可以用交互的方式执行Python语句。也就是执行一行Python语句,会立刻返回执行结果。

    蒙娜丽宁
  • Python编程思想(19):可变参数也可以这样玩

    很多编程语言都允许定义个数可变的参数,这样可以在调用函数时传入任意多个参数。Python当然也不例外,Python允许在形参前面添加一个星号(*),这样就意味着...

    蒙娜丽宁
  • 你所不知道的Python迭代器

    迭代就是循环的意思,也就是对一个集合中的元素进行循环,从而得到每一个元素。对于我们自定义的类,也可以让其支持迭代,这就是本文要介绍的特殊成员方法__iter__...

    蒙娜丽宁
  • Python面试题之Python中type和object的关系

    下面是jeff kit的回答: 给别人讲解过很多次,但写成文字是第一次。试一试吧,自己主要也是看了这篇文章(Python Types and Objects...

    Jetpropelledsnake21
  • C++服务器开发之笔记三

    为什么需要原子性操作? 我们考虑一个例子: (1)x++这个常见的运算符在内存中是怎样操作的? 从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x所处的内...

    用户1198337
  • html5总结

    用之前的标签完全可以代替的:header footer aside atrical nav address time mark section

    wfaceboss
  • python eval的常见错误封装及利

    最近在代码评审的过程,发现挺多错误使用eval导致代码注入的问题,比较典型的就是把eval当解析dict使用,有的就是简单的使用eval,有的就是错误的封装了e...

    py3study
  • Go语言中反射的正确使用

    介绍 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型。 反射有两个问题...

    李海彬
  • Json Schema 快速入门

    Json schema 本身遵循Json规范,本身就是一个Json字符串,先来看一个例子

    软测小生
  • Go语言中反射的正确使用

    介绍 反射是元数据编程的一种形式,指的是程序获得本身结构的一种能力。不同语言的反射模型实现不一样,本文中的反射,仅仅指的是Go语言中的反射模型。 反射有两个问题...

    李海彬

扫码关注云+社区

领取腾讯云代金券