《Python高级编程》(五)元类

定义

对象实例化原理:对象实例化过程中会调用__new__和__init__方法创建新对象;作为对象的类本身也是另一种类的实例,用于创建类。
元类:负责生成其他类的类就是元类(Metaclass)

类与对象

:相当于一个模板,具有创建对象的能力
元类:在python中,一切皆对象,p1,p2,p3…都是对象。负责生成其他类的类就是元类(Metaclass)
python中,一切皆对象,包括函数和类。
Person类也是对象,那么它由什么类创建的呢?
通过type函数我们就知道这个对象p1是由哪个类创建出来的:

        >>> class Person:
            pass
        >>> p1 = Person()
        >>> p1
        <__main__.Person object at 0x022EB790>
        >>> type(p1)  #查看p1是由哪个类创建的(Person)
        <class '__main__.Person'>
        >>> type(Person)  #查看Persion类是由哪个类创建的(type)
		<class 'type'> 
		>>> type(type)
		<class 'type'>

总结:

  • type是Python的内置类,该类是其他类对象的默认类。它是创建其他类的默认元类
  • 可以使用Type而非使用Python关键字Class创建类。
  • type构造函数接受3个参数:
    • name:类的名称
    • bases:该类的基类的元组
    • attrs:类中所以属性的字典
  • type是Python中的主要元类。是其他元类的基类,也是元类层级的最高级

使用type创建类

实质:其实在python中,我们使用class创建类,当你使用class关键字时,Python解释器自动创建这个对象。而底层其实使用的是type函数(type函数也可以查看实例所属类型)来创建类的。所以我们可以直接使用type()函数来手动实现动态创建类
使用Type创建类:

    def init(self, name):
    	self.name = name
    def eat(self):
        pass
    def go_to_vet(self):
        print "go_to_vet"
    Animal = type('Animal', (object,), {
        '__doc__': 'A class representing an arbitrary animal.',
        '__init__': init,
        'eat': eat,
        'go_to_vet': go_to_vet,
    })
    a = Animal('abc')
    print a.go_to_vet()

运行结果:
go_to_vet
None

解析:第二个参数是包含一个成员的元组:{object,}
表示:Animal类继承于object

使用type创建继承类:(继承于Animal而不是object)

    def meow(self):
    	return None
    def purr(self):
        print "---purr---"
        return None
    Cat = type('Cat', (Animal,), {
        'meow':meow,
        'purr':purr,
    })
    c = Cat('cat')
    print c.purr()

查看该对象是由什么类创建的可以使用type:

    print type(c)
    print type(int):type类是基类,位于链的顶端,因此type(type)返回其自身
    print type(5)
    <class '__main__.Cat'>
    <type 'type'>
    <type 'int'>

object是所有类的基类,是类继承链中的最高级
type也是元类层级的最高级

编写元类

  • 只需要声明一个继承自type的类(使用class关键字)
  • 类只是对象,元类也只是类。元类的行为继承自type;因此任何type的子类都可以作为元类
    class Meta(type):
    def __(cls, name, bases, attrs):
        return super(Meta, cls).____new____(cls, name, bases, attrs)

    C = Meta('C', (object,), {})
    print type(C)    #<class '__main__.Meta'>,即:该类是Meta的实例而不是type的实例
    #元类继承
    class D(C):
        pass
    print type(D)       #<class '__main__.Meta'>
  • 可以看出,C的子类D也是Meta实例,而不是type的直接实例
  • 大多数情况下类只有一个元类。即使在多继承的情况下,如果一个类的多个子类有不同的元类,python解释器会检查冲突。
    如果两个元类的一个并不是另一个的直接子类,python解释器会拒绝尝试执行。(报出异常)

type创建类和class创建类的比较

摘自:https://blog.csdn.net/qq_26442553/article/details/82459234

  • 使用type创建带属性和方法的类
class Person(object):
    def __init__(self,name):
        self.name = name
    def p(self):
        print("这是Person的方法")
class Animal(object):
    def run(self):
        print("animal can run ")
#定义一个拥有继承的类,继承的效果和性质和class一样。
Worker = type("Worker",(Person,Animal),{"job":"程序员"})
w1 = Worker("tom")
w1.p()
w1.run()
print(type(w1),type(Worker))
'''
这是Person的方法
animal can run 
<class '__main__.Worker'> <class 'type'>
<class '__main__.Person'>

总结:
- 通过type添加的属性是类属性,并不是实例属性
通过type可以给类添加普通方法,静态方法,类方法,效果跟class一样
- type创建类的效果,包括继承等的使用性质和class创建的类一样。本质class创建类的本质就是用type创建。所以可以说python中所有类都是type创建的。

  • type定义带继承,属性和方法的类

对元类理解

元类就是类的类,python中函数type实际上是一个元类。type就是Python在背后用来创建所有类的元类。Python中所有的东西——都是对象。这包括整数、字符串、函数以及类。它们全部都是对象,而且它们都是从一个类创建而来,这个类就是type。type就是Python的内建元类,当然了,也可以创建自己的元类。

使用元类

  • python3中:通过调用Meta创建类C
        class C(metaclass=Meta):
            pass
  • python3中,将_metaclass_属性赋给类:
        class C(object):
            __metaclass__ = Meta

何时使用元类

  • 大多数代码使用传统的类与对象的结构都没有问题,并不真的需要使用元类
  • 说明性类声明,例如Django模型
  • 类验证
  • 非继承属性

用的较少,以后再补充。

猜你喜欢

转载自blog.csdn.net/zhuix7788/article/details/86190963