zoukankan      html  css  js  c++  java
  • python类和对象的底层实现

    按照python中"一切皆对象的原理",所有创建的对象,都是一个已知存在的class实例化的结果;那么class又是被哪个"类"实例化的呢?先看下面的一段代码

    class Foo(object):
        pass
    
    obj = Foo()
    print type(obj)
    print type(Foo)
    
    结果为:
    <class '__main__.Foo'>
    <type 'type'>
    

    可以看到:obj是由Foo实例化,而Foo由type类创建

    这样Foo就可以这样实现了,看下面:

    def func(self):
        print "charles"
    
    Foo = type('Foo',(object,),{'func':func})
    print Foo
    f = Foo()
    f.func()
    
    结果为:
    <class '__main__.Foo'>
    charles
    

    那么问题随之产生了,既然class是由type实例化而来的,那么type中是如何实现类的创建的呢?

       实际上,在被type实例化的类中,有一个__metaclass__字段,指明由谁来实例化得到该类

    class MyType(type):
    
        def __init__(self, what, bases=None, dict=None):
            print "333"
            super(MyType, self).__init__(what, bases, dict)
    
        def __call__(self, *args, **kwargs):
            print "444"
            obj = self.__new__(self, *args, **kwargs)
    
            self.__init__(obj)
    
    class Foo(object):
    
        __metaclass__ = MyType
    
        def __init__(self):
            print '222'
    
        def __new__(cls, *args, **kwargs):
            print '1111'
            return object.__new__(cls, *args, **kwargs)
    
    obj = Foo()
    
    结果为:
    333
    444
    1111
    222
    

    可以看到Mytype和Foo都存在__new__()方法,那么这个方法是干什么的呢?

    __new__()函数:

    看下面:

    class A(object):
        def __init__(self):
            print 'init'
    
        def __new__(cls, *args, **kwargs):
            print "first"
            print object.__new__(cls,*args,**kwargs)
    A()
    
    结果:
    first
    <__main__.A object at 0x0000000002730EB8>
    

    可以看到__new__方法比__init__方法先执行,object.__new__(cls,*args,**kwargs)为A的实例化的对象,如果我打印self的话

    class A(object):
        def __init__(self):
            print self,'----'
            print 'init'
    
        def __new__(cls, *args, **kwargs):
            print "first"
            print object.__new__(cls,*args,**kwargs)
            return object.__new__(cls,*args,**kwargs)
    A()
    
    结果为:
    first
    <__main__.A object at 0x000000000260BE10>
    <__main__.A object at 0x000000000260BE10> ----
    init
    

    可以看到self的值,正好是__new__返回的结果;

    观察__new__返回的对象,参数中包含cls,表示当前的类,如果传入的不是当前的类(即使是父类),__init__不会被调用:

    class B(object):
        pass
    class A(B):
        def __init__(self):
            print self,'----'
            print 'init'
    
        def __new__(cls, *args, **kwargs):
            print "first"
            return object.__new__(B,*args,**kwargs)
    A()
    
    结果为:
    first
    <__main__.A object at 0x000000000238BEB8>
    

      

    结论:1、python的类的实例,是__new__方法创建的

           2、__new__方法必须有一个cls参数,表示当前类,只有传入的是当前cls,__init__才会被调用

           3、类的实例self,就是__new__方法return  object.__new__(cls,*args,**kwargs)的结果;

    参考:http://www.cnblogs.com/tuzkee/p/3540293.html

          http://www.cnblogs.com/wupeiqi/p/4766801.html

      

  • 相关阅读:
    python高级编程
    django笔记
    sublime ide
    python3 django mysql
    python win
    linux时区设置
    在实际应用中如何实现切圆角的功能
    display和visiblity在应用中使用哪个好
    看懂UML类图和时序图
    解决Xcode7.2真机调试出现:The account “” has no team with ID “”
  • 原文地址:https://www.cnblogs.com/cqq-20151202/p/6592168.html
Copyright © 2011-2022 走看看