• 元类


    # 元类
    # 说python当中一切皆对象,
    # 用class关键字定义的类其实本质也是一个对象。
    # class Foo:
    # pass
    # 说Foo是一个对象的话,对象肯定是由一个类实例化而来的。
    # 也就是说在class的时候,调class关键字的时候,必然是这个关键字去调了一个类的类,类的类就称之为元类。
    # 就是调了一个元类加括号实例化,元类加括号的结果就是用class定义的类
    # class Foo: # Foo = 元类()
    # pass
    # 所以说元类就是负责产生类的那一个类,是类的老祖宗。

    # 1.什么是元类?
    # 在python中一切皆对象,那么我们用class关键字定义的类本身也是一个对象
    # 负责产生该对象的类称之为元类,即元类可以简称为类的类


    # 2.为何要用元类?
    # 什么情况下用元类?
    # 元类是负责产生类的,可以控制类的产生过程,还可以控制对象的产生过程。
    # 什么叫对象的产生过程?
    # class Foo:
    # pass
    # Foo()
    # 对Foo这个类的产生控制,以及对调用Foo的这个过程的控制,因为调用Foo的过程就是产生Foo对象的过程


    # 3.如何用元类

    # 3.1 需要储备几点知识
    # 第一点知识: exec()这个内置函数

    # exec()这个内置函数用来干什么的呢?
    # 将一个字符串中的代码提出出来运行一下

    cmd = '''
    x=1
    y=2
    print('我爱老婆杨静,哈哈哈')
    '''
    local_dic = {}
    # exec(cmd,)
    # 模拟的就是执行python代码的过程,会产生一个名字,必然往名称空间里面去丢
    # 名称空间的格式是以字典的形式展现的
    # 所以造两个名称空间,一个全局名称空间
    # 怎么查看全局的名称空间:
    # print(globals())
    # 造一个空字典
    # local_dic = {}
    # exec(第一个参数是你的字符串,第二个参数是你要引用的那个全局作用域(不需要定义个空字典就好了),第三个是local_dic)
    exec(cmd,{},local_dic)
    print(local_dic)
    # 会发生什么是呢?
    # exec会执行字符串中的代码,将执行过程中产生的名字都往local_dic = {}里面丢
    # exec干了一件事:给你一段代码,只要执行过程中产生名字都丢到一个名称空间字典里面去。
    # 函数也可以!!
    # 函数体代码提取出来
    # def func():
    # x= 1
    # y=2
    # print('杨静爱老公张仁国,哈哈哈')

    # cmd = '''
    # x = 1
    # y = 2
    # print('杨静爱老公张仁国,哈哈哈')
    # '''
    # func_dic = {}
    # exec(cmd,{},func_dic)
    #
    # print(func_dic)

    # 类也可以!!
    # 类体代码提取出来

    cmd = '''
    x=1
    def func():
    y = 2
    '''
    class_dic = {}
    exec(cmd,{},class_dic)
    print(class_dic)
    # 类体执行过程中产生的名字都丢到名称空间里面去了
    # 这是模拟了类创建过程中类定义阶段造名称空间那一步操作


    # 用这个功能干嘛使?
    # 可以用来模拟造名称空间这个过程。


        # 3.2创建类过程当中有几个关键的要素
    # 创建类的方法有两种
    # 第一种class关键字去创建,用的是默认的元类:type
    # class People():
    # country = 'china'
    # def __init__(self,name,age):
    # self.name = name
    # self.age = age
    #
    # def eat(self):
    # print('%s is eating'%self.name)

    # # 查看People的类是谁:
    # print(type(People))
    # # <class 'type'>
    #
    # print(People)
    # obj = People('zrg',24)
    # print(obj)
    # obj.eat()
    # print(type(obj))

    # 大前提:如果说类也是对象的话,那么用class关键字去创建类的过程也是一个实例化的过程
    # 该实例化的目的是为了得到一个类,调用的是元类
    # 调用的元类又分为两种:
    # 一种是默认的元类type
    # 另一种是自定义的

    # 默认的元类的造类的过程:
    # 类的名字 class_name
    # 类的基类 class_bases
    # 类的名称空间 class_dic
    #
    # class_name = 'People' #类名必须是字符串形式
    # class_bases = (object,) #不继承任何类默认就是object逗号才叫一个元组
    # class_dic = {} #最关键的最难得,类的名称空间一个字典的形式
    # 类的名称空间从何而来----->从类体的执行而来,而类体就是一堆字符串
    # class_body = '''
    # country = 'china'
    # def __init__(self,name,age):
    # self.name = name
    # self.age = age
    #
    # def eat(self):
    # print('%s is eating'%self.name)
    # '''
    # 要做的事根据类体代码得到字典让他里面有值,就用exec函数
    # exec(class_body,{},class_dic)
    # 查看造类的三要素
    # print(class_name)
    # print(class_bases)
    # print(class_dic)

    # type(类名,基类,类的名称空间)得的结果给一个变量名People1
    # People1 = type(class_name,class_bases,class_dic)
    # print(People1)
    # obj1 = People1('yj',25)
    # obj1.eat()
  • 相关阅读:
    spring-session+Redis实现Session共享
    SQLServer语法常用总结
    [PDFBox]后台操作pdf的工具类
    类加载器
    SQLServer常用分页方式
    Tesseract识别图片提取文字&字库训练
    AbstractQueuedSynchronizer的简单介绍
    CountDownLatch 闭锁、FutureTask、Semaphore信号量、Barrier栅栏
    Java线程实现的第三种方式Callable方式与结合Future获取返回值
    原子类型的使用&Unsafe&CAS
  • 原文地址:https://www.cnblogs.com/zhangrenguo/p/10036990.html
Copyright © 2020-2023  润新知