Python 中type(name, base, dicts)与type.__new__(cls, name, base, dicts) 的区别

    看一个手写metaclass的实现:html

# -*- coding:utf-8 -*-
# 2017/6/29


class Meta(type):
    def __new__(mcs, *args, **kwargs):
        print "Meta new"
        return type.__new__(mcs, "meta_class", (), {})  # 1
        # return type('meta_class', (), {})  # 2

    def __call__(cls, *args, **kwargs):
        return super(Meta, cls).__call__()
        # raise RuntimeError("initialize not allowed")


def base_class_with_meta(cls, *base):
    class metaclass(Meta):
        def __new__(mcs, *args, **kwargs):
            return Meta(mcs, base, kwargs)

    return type.__new__(metaclass, "temp_meta_class", base, {})


class A(base_class_with_meta(Meta)):
    def __new__(cls, *args, **kwargs):
        return super(A, cls).__new__(args, kwargs)

    def __init__(self, *args, **kwargs):
        super(A, self).__init__(args, kwargs)


a = A()
b = A()

    输出python

D:\Python27\python.exe E:/workspace/lab_for_py/python-example-code/metaclass/test_metacalss_research.py
Meta new

Process finished with exit code 0

    看代码注释1和2局有什么区别函数

    分析:spa

    type(name, base, dicts)会生成一个新类,类的__name__ 为name, 基类为base,命名空间为__dict__code

不会调用类定义的init方法,此句返回是一个彻底的新类,和Meta没有任何关系htm

    type.__new__(cls, name, base, dicts)会返回一个cls的instance,会调用init方法,此类为Meta的实例对象

    附上文档:utf-8

    https://docs.python.org/3/reference/datamodel.html?highlight=__new__#object.__new__文档

    

    参考连接:get

    https://stackoverflow.com/questions/2608708/what-is-the-difference-between-type-and-type-new-in-python

    对元类的理解:

    在定义metaclass的时候__new__函数能够控制类对象生成的过程,__init__函数能够控制类对象的初始化,__new__和__init__  均可以控制类内参数(并不能控制类实例的参数),__call__函数能够控制类实例化变量的过程,好比实现单例。

    搞这些东西的人,大家听好了:

    Image result for 你他娘的真是我的才

相关文章
相关标签/搜索