由type()函数对类和实例使用结果差

发布时间:2019-10-14 09:21:37编辑:auto阅读(2194)

    有如下代码

    #-*-coding:utf-8-*-
    class a():
        pass
    a1 = a()
    print(type(a),type(a1))

    两个python版本分别为
    Python2.7.11
    Python3.5.1

    在python2中得到的结果
    (<type 'classobj'>, <type 'instance'>)
    a是一个类对象,a1是一个实例

    在python3中得到的结果
    <class 'type'> <class '__main__.a'>
    a是一个type?,a1是a的一个实例

    在python3中对一个类对象使用type()会得到type这个结果?

    解释?

    有人这样回答:

    这是因为type函数可以创建类
    其实class本质上就是type函数
    class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。
    
    
    In [2]: def fn(self,name = "world"):
       ...:     print("hello,%s" % name)
       ...:
    
    In [3]: Hello = type('Hello', (object,), dict(hello=fn))
    
    In [4]: h = Hello()
    
    In [5]: h.hello()
    hello,world
    
    In [6]: print(type(Hello))
    <class 'type'>
    
    In [7]: print(type(h))
    <class '__main__.Hello'>
    
    

    这就是用type函数创建类的实例
    要创建一个class对象,type()函数依次传入3个参数:

    class的名称; 继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
    class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。

    但是随后有人提出反对意见并说这个是metaclass,随后搜索到这篇文章

    深刻理解Python中的元类(metaclass) http://blog.jobbole.com/21351/

    里面介绍了如何使用type函数创建一个类(MyClass = type('MyClass', (), {})),并解释了__metaclass__属性。

    函数type实际上是一个元类
    当定义了一个类

    class Foo(Bar):
        pass
    

    Python做了如下的操作:

    Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(我说的是类对象,请紧跟我的思路)。如果Python没有找到__metaclass__,它会继续在Bar(父类)中寻找__metaclass__属性,并尝试做和前面同样的操作。如果Python在任何父类中都找不到__metaclass__,它就会在模块层次中去寻找__metaclass__,并尝试做同样的操作。如果还是找不到__metaclass__,Python就会用内置的type来创建这个类对象。

    因此,元类就是用来创建类的玩意。 type就是Python的内建元类(和str,int类似的性质),你也可以创建自己的元类。
    具体方法上面的文章中已经有了。

    “元类就是深度的魔法,99%的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。”
    —— Python界的领袖 Tim Peters

    感觉还是不要去碰的比较好。。。。。

关键字