专栏名称: Python程序员杂谈
关注PythonWeb开发及相关领域的方方面面,分享在实际工作中遇到的问题及解决方案。关注the5fire,了解Python开发的点点滴滴。
目录
相关文章推荐
51好读  ›  专栏  ›  Python程序员杂谈

Django源码中的metaclass使用是如何兼容Python2和Python3的

Python程序员杂谈  · 公众号  ·  · 2017-07-28 21:56

正文

请到「今天看啥」查看全文


Foo ( object ):

  • def __new__ ( cls , * args ):

  • return cls # 我们不返回实例了,直接返回类

  • def __init__ ( self , * args ):

  • self . name = 'the5fire'

  • foo = Foo ()

  • print ( foo ) # -->

  • 这种情况下得到的是Foo这个类,而不是实例。因此我们可以通过在 __new__ 这个方法里折腾点东西。

    这里总结下, __new__ 是来控制类创建的,而 __init__ 是来控制实例初始化的。

    理解type

    再来看type的使用,the5fire之前写的那篇 《Django分表的两个方案》 有说到怎么使用type动态创建类。可以通过这案例理解type的使用。而这里的type. new 是类似的,我们在ipython中看下这俩函数的说明:

    1. In [3]: type?

    2. Docstring:

    3. type(object) -> the object's type

    4. type(name, bases, dict) -> a new type

    5. Type:      type

    6. In [4]: type.__new__?

    7. Docstring: T.__new__(S, ...) -> a new object with type S, a subtype of T

    8. Type:      builtin_function_or_method

    type(name, bases, dict) 返回一个新的类型,继承自传递进入的bases(这个参数必须是tuple类型),以及拥有dict参数中定义的属性。 type.__new__(S, ...) 返回一个S类型的新对象,注意,这个新对象并不是我们平时写代码中的类的实例,而是类。因为S必须是type的子类(继承自type)。

    我们还是来通过代码认识下:

    1. # 1. 通过type创建类

    2. def class_creator(name):

    3.    return type(name, (), {})

    4. Person = class_creator('Person')

    5. print(Person, type(Person))  # --> (, )

    6. # 2. 通过type.__new__创建类

    7. def class_creator(name):

    8.    return type.__new__(type, name, (), {})

    9. Person = class_creator('Person')

    10. print(Person, type(Person))  # --> (, )

    11. # 3. 通过type.__new__创建一个自定义的类

    12. class CustomClass(type):

    13.    def __new__(cls, name, bases, attrs):

    14.        print('in CustomClass')

    15.        return type.__new__(cls, name, bases, attrs)

    16. def class_creator(name):

    17.    return type.__new__(CustomClass, name, (), {})

    18. Person = class_creator('Person')

    19. print(Person, type(Person))  # --> (, )

    把上面代码放到本地,运行下试试。

    其中[3]里面定义了 CustomClass.__new__ ,你运行过上面代码后发现并没有print出来"in CustomClass"的结果。这意味着通过 type.__new__ 创建的 CustomClass 的实例,并没有执行 __new__ 这个方法。







    请到「今天看啥」查看全文