一、初识type函数
type函数常用来判断对象属于什么类型,Python中一切皆对象的理念已深入人心,所以type函数使用频率也是挺高的。比如:
>>> a = 1
>>> b = 'hello'
>>> c = [1, 2, 3]
>>> d = {'name': 'Tom'}
>>> e = (1, 2, 3)
>>> type(a)
>>> type(b)
>>> type(c)
>>> type(d)
>>> type(e)
上面出现的几种对象类型很常见,比如“int”、“str”、“list”、“dict”’等。我们再看看下面的例子:
>>> class Student(object): pass
...
>>> s = Student()
>>> type(s)
>>> type(Student)
对于实例对象s属于Student类,这个比较容易理解;但是,为什么Student类对象属于type类呢?type类又是什么呢?(注意:类本身也是对象)再看几个例子:
>>> type(int)
>>> type(str)
>>> type(dict)
>>> type(tuple)
上面的结果表现的极其一致,结合上面举的Student类的例子,可以初步得出结论,不管是Python自带的像“int”、“list”等类对象,还是像Student这样自定义的类对象(注意:是类对象,不是实例对象),都是属于type类。
二、再识type函数
除了可以通过type函数判断对象类型,还可以通过__class__属性获取,试试这种方式:
>>> a = 1
>>> a.__class__
>>> a.__class__.__class__
>>> a.__class__.__class__.__class__
对于类对象属于type类型的结果还没能接受,现在又冒出来type类也属于type类的结果,如果你愿意继续测下去,a.__class__.__class__.__class__.__class__的结果还是type。
现在看来,type类真的神秘,到底为何物?
以下是Python官方文档对type类的解释:
Type objects represent the various object types. An object’s type is accessed by the built-in function. There are no special operations on types. The standard module
Types are written like this: .
大致意思:type类代表了各种各样的对象类型,像“int”这样的对象类型是通过type()函数获取的。所有内置的标准对象类型都在这里types。
可能有人会有疑惑,为什么对象类型是通过type()函数创建的呢?明明是通过通过class类进行定义的。这就要涉及到type()函数另一种使用方式了:
classtype(name,bases,dict)
向type()函数传入三个参数name,bases,dict(参数稍后解释),将会返回一个新的type对象(比如内置int对象就是属于type类,还有自定义Student类对象也属于type类),至此感觉type()函数好强大,它似乎创造了Python所有的对象,事实也是如此。
等等,我们明明使用class定义的类,怎么和type()函数扯上关系了呢?当我们使用class定义类的时候,Python解释器仅仅是扫描一下定义的语法,然后调用type()函数创建class类。那为什么采取这种方式呢?先看一个例子:
class A(object):
# 类属性
role = 'student'
# 实例方法
def __init__(self, name):
# 实例属性
self.name = name
# 类方法
@classmethod
def study(cls):
pass
# 静态方法
@staticmethod
def cal_student_num():
pass
上面我们使用class定义了A类对象,其中包含了类属性、类方法、实例属性、实例方法、静态方法。如果我们使用type()函数,如何创建呢?
# 使用type()函数定义类
# 实例方法
def __init__(self, name):
# 实例属性
self.name = name
# 类方法
@classmethod
def study(cls):
pass
# 静态方法
@staticmethod
def cal_student_num():
pass
# 元类最大的作用不在于创建一个新的类
A = type(
'A',
(object,),
{
'role': 'student',
'__init__': __init__,
'study': study,
'cal_student_num': cal_student_num
})
仔细观察,使用type()函数创建class类的时候,只是将定义在class类内部的代码拿出来,放在外面,然后向type()函数传入三个参数name,bases,dict。name字符串类型,代表类名,比如例子中的"A";bases元组类型,代表基类(或父类),即需要继承的类对象;dict字典类型,将定义的类属性、类方法、实例方法等,以键值对的形式建立映射关系。
当我们使用class定义对象的时候,解释器内部会帮我们调用type()函数,完成创建对象工作。为什么平时我们定义对象大多是采用class,而不采用type()函数呢?因为type()函数一点都不优美,看上去缺少整体性,代码不易读,写起来也很麻烦。(如果一般工作中用type()定义对象,估计要被骂,哈哈 )
说明:
name参数变成
In [6]: A.__class__
Out[6]: type
In [7]: A.__bases__
Out[7]: (object,)
In [8]: A.__dict__
Out[8]:
mappingproxy({'__dict__': ,
'__doc__': None,
'__init__': ,
'__module__': '__main__',
'__weakref__': ,
'cal_student_num': ,
'role': 'student',
'study': })
三、小结使用type()函数时,如果只传入一个参数object,那么将返回该object的类型;
如果分别传入name,bases,dict这三个参数,那么type()函数将会创建一个对象;
使用class定义对象的时候,Python解释器调用type()函数来动态创建对象。