一、概念
-
在Python中, 有一个概念, 那就是
万物皆对象, 意思就是说, 在Python中, 所有的数据全部都是对象, 包括数据类型10和字符串"abc" -
可以使用
__class__属性, 查看10和"abc"的类型
num = 10
print(num.__class__) # 打印: <class 'int'>
s = "abc"
print(s.__class__) # 打印: <class 'str'>
- 我们自己定义的类, 实例化的对象也可以使用
__class__查看类型
class Person:
pass
p = Person()
print(p.__class__) # 打印: <class '__main__.Person'>
-
现在我们知道, 上面的
int、str和Person都是类 -
实际上, 在Python中, 这些类本身也是一种对象, 我们称之为
类对象 -
我们可以使用类对象的
__class__属性, 查看对象属于哪一个类
print(int.__class__) # 打印: <class 'type'>
print(str.__class__) # 打印: <class 'type'>
print(Person.__class__) # 打印: <class 'type'>
-
由打印可知,
int、str和Person这三个类对象, 都是被type创建出来的 -
我们再看看
type的__class__属性
print(type.__class__) # 打印: <class 'type'>
-
可以发现类对象
type, 是由它本身类type创建出来的 -
type:Python中最底层的类, 我们称它为元类, 是一个能够创建出类对象的类
二、类对象的创建方式以及创建流程
- 我们知道, 可以通过下面的方法定义一个类对象
class Dog:
def run(self):
print("奔跑吧" --- self)
- 同时, 我们还可以使用元类
type创建一个类对象
1、类的创建方式
- 已知, 可以使用
type(对象), 来查看对象的类型
num = 10
print(type(num)) # 打印: <class 'int'>
-
实际上,
type()函数还有另外一个使用方法, 那就是创建一个类对象 -
type("类名", (父类), {属性方法})类名: 要创建类的名称(父类): 指定所创类对象的父类, 为空时表示没有父类{属性方法}: 指定类对象有哪些类属性和方法- 返回值: 类对象
# 定义函数 run
def run(self):
print("奔跑吧" --- self)
type("Dog", (), {"count" : 1, "run" : run})
- 上面的代码就是创建了一个
Dog类对象 - 不过这段代码所创建的类对象并没有被任何变量引用, 所以我们无法使用, 想要使用必须使用一个变量接收
# 定义函数 run
def run(self):
print("奔跑吧 --- ", self)
xxx = type("Dog", (), {"count" : 1, "run" : run})
- 打印
xxx, 查看它的类型
print(xxx) # 打印: <class '__main__.Dog'>
- 通过
xxx创建一个属于Dog类的实例化对象
d = xxx()
print(d) # 打印: <__main__.Dog object at 0x104a1f7f0>
- 直接调用
count属性和run方法
print(d.count) # 打印: 1
d.run() # 打印: 奔跑吧 --- <__main__.Dog object at 0x10451f7f0>
2、类的创建流程
-
上面已经给出了使用
type创建一个类的方式, 实际上, 要创建一个类的时候, 并不是必须使用元类type, 我们也可以自己定义一个元类, 然后使用这个元类创建类 -
在定义类的时候, 可以使用
__metaclass__属性, 指定创建该类的元类 -
假设, 现在有一个元类, 名字叫
xxx, 我们可以使用下面的两种方法, 以xxx为元类创建类对象
class Person:
__metaclass__ = xxx
class Person(metaclass = xxx):
pass
- 默认情况下
__metaclass__属性的值是空的, 创建类时, 会根据下面的流程查找创建类所需的元类
1. 查看自身是否有明确的__metaclass__属性
2. 查看父类是否存在__metaclass__属性
3. 查看模块是否存在__metaclass__属性
4. 通过内置的type这个元类, 来创建这个类对象
- 当自身没有明确的
__metaclass__属性时, 使用父类的__metaclass__创建类对象
class Animal:
__metaclass__ = xxx
class Person(Animal):
pass
- 当父类也没有
__metaclass__属性时, 使用模块中的__metaclass__属性创建类对象
__metaclass__ = xxx
class Person:
pass
- 如果连模块中也没有明确的
__metaclass__属性, 此时就会使用Python内置的type元类, 创建类对象
class Person:
pass