由type()函数对类和实例使用结果差异而引出的一个问题

有如下代码

#-*-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

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

相关推荐