创建类的两种方式
方式一:使用class关键字
class Chinese(object): country='China' def __init__(self,name,age): self.name=name self.age=age def talk(self): print('%s is talking' %self.name)
方式二(就是手动模拟class创建类的过程):将创建类的步骤拆分开,手动去创建
准备工作:
创建类主要分为三部分
1 类名
2 类的父类
3 类体
#类名 class_name='Chinese' #类的父类 class_bases=(object,) #类体 class_body=""" country='China' def __init__(self,name,age): self.name=name self.age=age def talk(self): print('%s is talking' %self.name) """
步骤一(先处理类体->名称空间):类体定义的名字都会存放于类的名称空间中(一个局部的名称空间),我们可以事先定义一个空字典,然后用exec去执行类体的代码(exec产生名称空间的过程与真正的class过程类似,只是后者会将__开头的属性变形),生成类的局部名称空间,即填充字典
class_dic={} exec(class_body,globals(),class_dic) print(class_dic) #{'country': 'China', 'talk': <function talk at 0x101a560c8>, '__init__': <function __init__ at 0x101a56668>}
步骤二:调用元类type(也可以自定义)来产生类Chinense
Foo=type(class_name,class_bases,class_dic) #实例化type得到对象Foo,即我们用class定义的类Foo print(Foo) print(type(Foo)) print(isinstance(Foo,type)) ''' <class '__main__.Chinese'> <class 'type'> True '''
我们看到,type 接收三个参数:
-
第 1 个参数是字符串 ‘Foo’,表示类名
-
第 2 个参数是元组 (object, ),表示所有的父类
-
第 3 个参数是字典,这里是一个空字典,表示没有定义属性和方法
补充:若Foo类有继承,即class Foo(Bar):.... 则等同于type('Foo',(Bar,),{})
一个类没有声明自己的元类,默认他的元类就是type,除了使用元类type,用户也可以通过继承type来自定义元类
1.任何名字后加括号,都是在调用一个功能,触发一个函数的执行,得到一个返回值,类或对象加括号触发的是__call__的运行 2.__new__更像是其他语言中的构造函数,必须有返回值,返回值就实例化的对象 3.__init__只是初始化函数,必须没有返回值,仅仅只是初始化功能,并不能new创建对象
前提注意:
1. 在我们自定义的元类内,__new__方法在产生obj时用type.__new__(cls,*args,**kwargs),用object.__new__(cls)抛出异常:TypeError: object.__new__(Mymeta) is not safe, use type.__new__()
2. 在我们自定义的类内,__new__方法在产生obj时用object.__new__(self)