Python 面向对象2_元类-抽象基类

元类

type:创建类的类,称之为元类

class A():
    pass

a = A()
print(type(a))  #<class '__main__.A'>  # 实例所属的类
print(type(A))  #<class 'type'>        # A类所属的类
print(type(type)) #<class 'type'>      # 元类所属的类 

type创建类

  • 语法:
    type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
  • 创建类:
    MyClass = type(‘MyClass’, (), {})

函数type实际上是一个元类, type就是Python在背后用来创建所有类的元类(类工厂)
如:1 -> int -> type
type就是Python的内建元类,我们也可以创建自己的元类。

class Animal():
    def __init__(self, name):
        self.name = name
    def eat(self):
        print("i am eating...")

def eat(self):  # 注:属性/方法 写在外面
    print("dog is eating...")
def __init__(self, name):
    self.name = name
###type语法创建类,第1个参数是 类名,第2个参数 是继承关系(元组形式),第3个参数是 属性和方法(字典形式)
Dog = type("Dog",(Animal,),{"eat":eat})	# 注:使用type语法去创建类
dog = Dog("peiqi")
dog.eat()
#结果为 dog is eating...

#创建Animal类
Animal = type("Animal",(object,),{"eat":eat,"__init__":__init__})

面向对象里有俩种关系:
继承关系: object 是所有类的父类,是最顶层的类
实例与类的关系: 创建关系 type就是最顶层的类,就是元类

自定义元类

class MyMeta(type): # 注:继承type
    def __init__(self, *args):
        print("test my metaclass")  # 注:初始化时输出

class Foo(metaclass=MyMeta):    # 注:默认参数是type   使用MyMeta创建Fool
    def __init__(self):
        print("Fool__init__")
#结果为 test my metaclass

print(Foo.__bases__)            # 注:Foo的__bases__是 object
#结果为 (<class 'object'>,)

自定义元类,为每个类创建一个func方法,这个方法输出当前创建的类有哪些属性

class MyMate(type):
    def __new__(cls, name, bases, attrs):
        attrs["func"] = cls.func
        return type.__new__(cls, name, bases, attrs)

    def func(self):
        return dir(self)

class A(metaclass=MyMate):
    age = 10

a = A()
print(a.func())
# ['__class__', '__delattr__', '__dict__', '__dir__',...]

元类的主要目的就是为了当创建类时能够自动地改变类
·拦截类的创建
·修改类
·返回修改之后的类

拦截创建类

元类可以规定类创建时候的一些行为,拦截类创建的,对类设置做规范时

class MyMeta(type): # 注:继承type
    def __new__(cls, name, bases, attrs):   # 注:在__new__里面管理创建它 需要接收参数 这样传递(因为要把attrs捞出来判断)(或者可变长位置参数传递)
        if "name" not in attrs:# 注:属性是字典类型的参数   type创建需要传递三个变量
            raise TypeError("必须设置属性name")
        attrs["test"] = "my mate test"
        return type.__new__(cls, name, bases, attrs)    # 注:元类里使用type的__new__去返回创建 把这些参数传递进去
        # 注:不可能自己创建__new__的方法,使用type的__new__去创建

class A(metaclass=MyMeta):    # 注:用自定义元类去创建
    name = "wy"

#结果为     raise TypeError("必须设置属性name")  # 注:A类中没有设置name属性时
# TypeError: 必须设置属性name

a = A() # 注:A的父类是object
print(a.test)
#结果为 my mate test
#把传进来的属性 先交给MyMeta去创建/添加 最后再交给type去创建

抽象基类

定义了接口规范
子类必须实现父类里的抽象方法
抽象基类不能实现实例化

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod  # 被装饰器装饰的方法
    def eat(self):   # 抽象方法
        pass         # 抽象方法不需要具体的实现
    def drink(self):
        pass

class Dog(Animal):
    # pass
    def eat(self):# 该方法没被重写就会报错
        print("dog is eating...")

d = Dog()  # 实例化的时候,子类必须实现父类里面的抽象方法
# 如果没实现,会报TypeError: Can't instantiate abstract class Dog with abstract method eat
d.eat()
#结果:dog is eating...
# a = Animal()    #注:报错 抽象基类不可以实例化
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这个手刹不太灵儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值