栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python 面向对象2

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python 面向对象2

文章目录
  • 元类
    • type创建类
    • 自定义元类
    • 拦截创建类
  • 抽象基类

元类

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

class A():
    pass

a = A()
print(type(a))  #  # 实例所属的类
print(type(A))  #        # A类所属的类
print(type(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
#结果为 (,)

自定义元类,为每个类创建一个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()    #注:报错 抽象基类不可以实例化
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/846408.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号