python中的元类大家都可能比较很陌生,因为大家都听说过99%的情况下是用不到元类的,但是大家对类确很了解,大家都知道在python中万物皆对象,那么python中的类是不是对象呢?
对象的样子:
1,对象可以在程序中动态的进行创建,python的语言动态特性。
2,对象可以通过__class__获取该对象所属的类。
3,对象可以动态的添加属性,方法。
4,可以使用type查看对象的类型。
class Person(object): pass class Student(object): pass class Student_son(Student): pass input_text = input('输入person,创建person,输入student,创建student。。。') if input_text == 'person': obj = Person() elif input_text == 'student': obj = Student() else: obj = Student()
看上面的代码,三个类实现了动态创建,所以非常满足第一条对象的样子。再看下面的代码,就可以看到Person类完全符合对象的样子2,3,4。
class Person(object): def __init__(self): pass p = Person() print(Person.__class__) Person.name = '白银' Person.sayName = lambda a : print('我的名字是', a) Person.sayName(Person.name) print(type(Person))执行结果:
<class 'type'> 我的名字是 白银 <class 'type'>
也就是说:
1,类可以在程序中动态的创建。
2,类可以通过__class__获取该对象所属的类。
3,类是可以动态的添加属性和方法。
4,类可以使用type查看该对象的类型。
可能我花费了很多时间和精力来证明,类也是对象:
def create_class(class_name): if class_name == 'Person': class Person(object): def __init__(self): print('我是Person') return Person elif class_name == 'Student': class Student(object): def __init__(self): print('我是Student') return Student elif class_name == 'StudentSon': class StudentSon(object): def __init__(self): print('我是StudentSon') return StudentSon else: print('无法创建', class_name) class_create = create_class('Student') print(class_create.__class__) class_create.gender = '男' class_create.sayHello = lambda : print('hello world') print(class_create.gender) class_create.sayHello()
print(type(class_create))
执行结果:
<class 'type'> 男 hello world
<class 'type'>
那么结论就是:
python中的类,本质上也是一个对象,type就是元类,就是创建类的类.
这个类就是我们所说的type,从源开始说的话,我们中国有一句古话叫做:道生一,一生二,二生三,三生万物,而这句古话特别吻合我们所说的元类到类,在到对象和属性方法。也就是说,道就是元类,类对象(metaclass)是二,对象是三,对象的属性和方法是万物。是不是特别吻合,好吧佩服一下咱们老祖宗的智慧把。
type的用法:
1,查看当前对象的类型
2,创建类
语法:type(类名,继承父类的元组,包含属性的字典)
Person = type('Person', (object,), {}) Student = type('Student', (Person,), {'name': '张飞龙', 'say_hello': lambda self: print('大家好,我是', self.name)}) student = Student() print(type(student)) print(student.name) student.say_hello()
以上代码通过type创建一个Person类,然后创建的Student类继承了Person,并且有字典的传入,实例化的对象student继承了name属性和say_hello方法。
<class '__main__.Student'> 张飞龙 大家好,我是 张飞龙
3,type原理:
使用type创建类,实际上是:
Student = type()返回的一个类对象
student = Student()
所以,type实际上就是python中给我们提供的元类。
4.自定义元类:
你可以在写一个类的时候为其添加__metaclass__属性,定义了__metaclass__就是定义了这个类的元类。
语法:
class Person(__metaclass = somecode):somecode 必须返回一个类
pass
作用:
可以让创建出来的类符合自己想要的标准
执行流程:
首先查找当前类中是否有__metaclass__,如果有,则在内存中创建Person这个类对象。
如果当前类没有,则去父类中查找是否有__metaclass__.如果有,则创建类对象 。
如果当前类的父类中也没有__metaclass__。则去当前模块中找。
如果模块中也没有,则使用type进行创建person类对象
# 要求,创建出的所有类,除了私有属性外,其余属性都要大写 def upper_attr(class_name, class_Parent, class_attrs): # 这个字典用来存储属性和值 attrs = {} for name, value in class_attrs.items(): if not name.startswith('__'): attrs[name.upper()] = value return type(class_name, class_Parent, attrs) class Myclass(object, metaclass=upper_attr): def __init__(self, name, age): self.name = name self.age = age test1 = 'test' a = 'a' __b = 'b' bb = 'bb' green = '绿色' my_class = Myclass() print(hasattr(Myclass, 'a')) print(hasattr(Myclass, 'A'))
在上面的例子中,我们定义了一个upper_attr函数用来返回一个类,而这个类作为我们接下来定义的Myclass类的元类,这个元类的元类就是type,因为它是type()函数里出来的,在upper_attr里我们把他本身的方法修改了大写。最后执行代码:
False True