我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python深入浅出分析元类

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python深入浅出分析元类

一、类和对象

Python属于动态类型的语言,而动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时创建的,而是运行时动态创建的,比方说我们要定义一个 Person 的class,就写一个 Person.py 模块:

# -*- coding: utf-8 -*-
# 文件名  : Person.py
class Person(object):
    def say(self, s='元类'):
        print('今日学习:%s' % s)
if __name__ == '__main__':
    p = Person()
    p.say()

当Python解释器载入 Person 模块时,就会依次执行该模块的所有语句,执行结果就是动态创建出一个 Person 的class对象,测试如下,(注意,是引入一个Person.py脚本)

# 文件名 :测试.py
# 引入模块,需要模块的路径
from Person import Person
# 创建一个Person类的实例
p = Person()  
p.say('Python中的元类')  # 调用say方法
# 今日学习:Python中的元类
print(type(p))  # 把实例 p 的类型打印出来
# <class 'say.Person'>
print(type(Person))  # Person 类的类型打印出来
# <class 'type'>

这里是用来 type() 函数,可以查看一个类型或变量,的类型, Person 是一个class,它的类型就是 type ,而 p是一个实例,它的类型就是class Person

二、type类

我们说class的定义是运行时动态创建的,而创建class的方法就是使用 type() 函数

type() 函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过 type() 函数创建出Person 类,而无需通过 class Person(object)... 的定义,此时type的第二种用法,我们只要type传object是可以返回该对象类型的,但是当我们的type存在三位参数存在时

# type 类
class type(object):
    """
    type(object_or_name, bases, dict)
    type(object) -> the object's type
    type(name, bases, dict) -> a new type
    """
#参数介绍
"""    
type(object_or_name, bases, dict)
object-or-name -- 对象或类的名称。
bases -- 基类的元组。
dict -- 字典,类内定义的命名空间变量。
"""
# 返回新的类型对象。
# -*- coding: utf-8 -*-
def fun(self, s):
    print('hello'+s)
Hello = type('hello', (object,), dict(func=fun))
if __name__ == '__main__':
    h = Hello()
    h.func(' word')
    # hello word
    print(type(h))
    # <class '__main__.hello'>
    print(type(Hello))
    # <class 'type'>  

我们通过 type() 函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用 type() 函数创建出class

在正常情况下,我们都用 class Xxx... 来定义类,但是, type() 函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂

三、元类Metaclass

除了使用 type() 动态创建类以外,要控制类的创建行为,还可以使用metaclass,也就是元类

当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例

但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类,元类就是用来创建这些类(对象)的,元类就是类的类

我们先看一个简单的例子,这个metaclass可以给自定义的类增加一个 add 方法定义 ListMetaclass ,按照默认习惯,metaclass的类名总是以Metaclass结尾,以便清楚地表示这是一个metaclas。

四、自定义一个元类

class UpperMetaclass(type):
    def __new__(mcs, class_name, class_parents, class_attrs):
        new_attrs = {}
        for name, value in class_attrs.items():
            if not name.startswith('__'):  # 判断是否为非私有属性
                new_attrs[name.upper()] = value
        # 直接调用type 来创建一个类
        return type.__new__(mcs, class_name, class_parents, class_attrs)
# 测试
class Emp(object, metaclass=UpperMetaclass):
    name = '张三'
    acl = 500
if __name__ == '__main__':
    print(hasattr(Emp, 'name'))  # 判断Emp中是否有名字为name
    print(hasattr(Emp, 'NAME'))  # 判断Emp中是否有名字为NAME

到此这篇关于Python深入浅出分析元类的文章就介绍到这了,更多相关Python元类内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python深入浅出分析元类

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

深入浅出分析LinkedHashMap(图文)

一、摘要在集合系列的第一章,咱们了解到,Map的实现类有HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties等等。本文主要从数据结构和算法层面,探讨Link
深入浅出分析LinkedHashMap(图文)
2019-02-22

React深入浅出分析Hooks源码

在react类组件(class)写法中,有setState和生命周期对状态进行管理,但是在函数组件中不存在这些,故引入hooks(版本:>=16.8),使开发者在非class的情况下使用更多react特性
2022-11-13

深入浅析Collections工具类

深入浅析Collections工具类?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Collections工具类提供了大量针对Collection/Map的操作,总体可分为四
2023-05-31

深入浅析Java中的Object类

今天就跟大家聊聊有关深入浅析Java中的Object类,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java作为一个庞大的知识体系,涉及到的知识点繁多,本文将从Java中最基本的类j
2023-05-31

深入浅析Java中的 List类

本篇文章给大家分享的是有关深入浅析Java中的 List类,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。List:元素是有序的(怎么存的就怎么取出来,顺序不会乱),元素可以重复
2023-05-31

深入浅析Java中的Properties类

今天就跟大家聊聊有关深入浅析Java中的Properties类,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java中Properties类的操作 知识学而不用,就等于没用,到
2023-05-31

深入浅析Java中的String类

这期内容当中小编将会给大家带来有关深入浅析Java中的String类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。引题在Java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时
2023-05-31

深入浅出Sqoop之迁移过程源码分析

【摘要】 Sqoop是一种用于在 Apache Hadoop 和结构化数据存储(如关系数据库)之间高效传输批量数据的工具 。本文将简单介绍Sqoop作业执行时相关的类及方法,并将该过程与MapReduce的执行结合,分析数据如何从源端迁移到目
深入浅出Sqoop之迁移过程源码分析
2016-04-28

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录