• 元类(metaclass)


    参考链接:https://www.cnblogs.com/busui/p/7283137.html

                      http://developer.zhiding.cn/2008/0521/874673.shtml

    1.    type()的两种功能

    功能1:可以查看类型或变量的类型,此时相当于是一个函数;    

    type("100")------>str

    功能2:可以创建出新的类型,此时就是元类;

    用法:type(类名, 由父类名称组成的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))——注:等价于


    使用type创建class

    和type创建class是等价效果

    2.    __class__属性和__bases__属性

    objectname.__class__:查看对象是由哪个类实例化得来的,和type()功能1的效果是一样的;注——对应的是类型关系。

    objectname.__bases__:查看对象的超类是哪些,元组的形式表达;注——对应的是继承关系。

    3.    python中一切皆对象

    object和type是python中两个源对象


     

    (1),(2):python中的两个源对象的名字。我们先前说过type()是用来获对象的类型的。事实上,它既是一个对象,也是获取其它对象的类型的方法。

    (3),(4):查看object的类型。看到object是type的实例,我们另外也用.__class__来核实它和type()的输出是一样的。

    (5):object没有超类,因为它本身就是所有对象的超类。

    (6),(7):分别输出type的类型和超类。即,object是type的超类。type的类型是它自己

    总结,type和object的关系图如下:


    鸡生蛋,蛋生鸡。。。
     

    鸡生蛋,蛋生鸡。。。

    class定义的类也是对象,即在内存中也会有相应空间与之对应;类对象 具有的创建 实例对象 的能力;

    globals()函数可以查看所有的全局变量的引用;

    4.    python中对象的种类

    在python中,创造的新对象有两种:类型对象和非类型对象。

    类型对象:可被继承和实例化。

    非类型对象:本身就是一个实例,没有超类(父类/基类)。当python创造新对象时,它会用自己本身的类型作为新对象的类型。一般会用到两个方法__new__()和__init__()。所以。每个对象都有类型。

    5.    python中对象与对象之间的关系

    Python对象之间有两种导航关系:继承关系和类型关系

    类型关系:说明一个对象是通过哪个对象创建的;

    继承关系:对象之间的父子关系,继承关系只发生在类型对象之间;

    6.    进入主题啦,什么是元类(metaclass)?

    python中默认type就是元类!!!即metaclass = type


    metaclass = type

    Q:能不能指定metaclass呢?让它不是type呢?

    A:可以的,不过还是要通过return,返回type元类来实现,只是这种应用的情景很少,基本不会用到,下面是一种用法;因为 type(类名, 由父类名称组成的元组,包含属性的字典),所以在定义新的元类的时候这些参数


     
    #coding=utf-8
    
    class UpperAttrMetaClass(type):  # 此时 UpperAttrMetaClass 继承了type,它就变成里元类了。
        # __new__ 是在__init__之前被调用的特殊方法
        # __new__是用来创建对象并返回之的方法
        # 而__init__只是用来将传入的参数初始化给对象
        # 你很少用到__new__,除非你希望能够控制对象的创建
        # 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__
        # 如果你希望的话,你也可以在__init__中做些事情
        # 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用
        def __new__(cls, class_name, class_parents, class_attr):
            # 遍历属性字典,把不是__开头的属性名字变为大写
            new_attr = {}
            for name, value in class_attr.items():
                if not name.startswith("__"):
                    new_attr[name.upper()] = value
    
            # 方法1:通过'type'来做类对象的创建
            return type(class_name, class_parents, new_attr)
    
            # 方法2:复用type.__new__方法
            # 这就是基本的OOP编程,没什么魔法
            # return type.__new__(cls, class_name, class_parents, new_attr)
    
    # python3的用法
    class Foo(object, metaclass=UpperAttrMetaClass):
        bar = 'bip'
    
    # python2的用法
    # class Foo(object):
    #     __metaclass__ = UpperAttrMetaClass
    #     bar = 'bip'
    
    
    print(hasattr(Foo, 'bar'))
    # 输出: False
    print(hasattr(Foo, 'BAR'))
    # 输出:True
    
    f = Foo()
    print(f.BAR)
    # 输出:'bip'
    升级版

    7.    元类、类、实例的关系

    元类——》类——》实例

    注:在较旧的python版本中,类型和类是泾渭分明的:内置对象是基于类型的,而自定义对象是基于类的,你可以创建类,但是你不能创建类型。在python3中,已经不再区分类型和类了,所以不要再纠结这点了。

    作者:David-lcw
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    关于浮动清除的一些小感悟,4种方法清除浮动
    6号css学习小记
    pexpect-pxssh-登陆Linux-执行命令
    chroot命令
    Loadrunner11点击录制脚本无响应,IE页面弹不出——解决方案汇总
    JAVA实验五(网络编程)
    Java实验三
    JAVA实验二(面向对象)
    JAVA实验一
    Tfs链接错误解决方案
  • 原文地址:https://www.cnblogs.com/david-lcw/p/10011069.html
Copyright © 2020-2023  润新知