• 反射函数与元类


    一.反射函数

    反射:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

    python面向对象中的反射:通过字符串的形式操作对象相关的属性。

    四种内置方法:getattr   setattr  delattr  hassttr

    getattr:从对象中取出属性,第三个值位默认值 当属性不存在是返回默认值

    setattr:为对象添加新的属性

    delattr:从对象中删除属性

    hasattr:判断object中有没有一个name字符串对应的方法或属性

    class Person:
    
        def __init__(self,name,age,sex):
            self.age = age
            self.name = name
            self.sex = sex
    
        def Say_hi(self):
            print('you are handsome')
    
    
    p = Person("dragon",58,'male')
    
    setattr(p,'id','123')
    print(p.id)
    delattr(p,'id')
    if hasattr(p,'id'):
        getattr(p,'Say_hi',None)()
    View Code

    反射函数的应用场景:实现可插拔机制与动态导入模块

    可插拔机制

    import plugin
    
    def run(plugin):
        while True :
            cmd = input('请输入指令')
    
            if cmd == 'exit':
                break
            if hasattr(plugin,cmd):
                func = getattr(plugin,cmd)
                func()
    
            else:
                print('该指令不存在')
    
        print('see you')
    
    wincmd = plugin.Wincmd()
    linux  = plugin.Linuxcmd()
    
    run(linux)
    # from frame
    
    class Wincmd :
        def cd(self):
            print("wincmd 切换目录....")
    
        def delete(self):
            print("wincmd 要不要删库跑路?")
    
        def dir(self):
            print("wincmd 列出所有文件....")
    
    class Linuxcmd :
    
        def cd(self):
            print("Linuxcmd 切换目录....")
    
        def rm(self):
                print("Linuxcmd 要不要删库跑路?")
    
        def ls(self):
                print("Linuxcmd 列出所有文件....")
    # from plugin
    View Code

    二.元类

    python中一切皆为对象,类的本质也是一个对象。

    元类:可以通过实例化产生类

    python中内置的元类TYPE,可以通过继承TYPE来构建自定义元类

    使用metaclass关键字参数可以为一个类指定元类

    方法:

    call方法:

    当你调用类对象时会自动启动元类中的__call__方法 ,并将这个类本身作为第一个参数传入,以及后面的一堆参数

    覆盖元类中的call之后,这个类就无法产生对象,必须调用super().__call__来完成对象的创建
    并返回其返回值

    使用场景:

    当你想要控制对象的创建过程时,就覆盖call方法

    当你想要控制类的创建过程时,就覆盖init方法

    #实现将对象的所有属性名称转为大写
    lass MyType(type):
        def __call__(self, *args, **kwargs):
            new_args = []
            for a in args:
                new_args.append(a.upper())
    
            print(new_args)
            print(kwargs)
            return super().__call__(*new_args,**kwargs)
    
    
    class Person(metaclass=MyType):
        def __init__(self,name,gender):
            self.name = name
            self.gender = gender
    
    p = Person(name="jack",gender="woman")
    print(p.name)
    print(p.gender)
    View Code

    new方法:

    当你要创建类对象时,会首先执行元类中的__new__方法,拿到一个空对象,然后会自动调用__init__来对这个类进行初始化操作
    注意:,如果你覆盖了该方法则必须保证,new方法必须有返回值且必须是,对应的类对象

    class Meta(type):
    
        def __new__(cls, *args, **kwargs):
            print(cls) # 元类自己
            print(args) # 创建类需要的几个参数  类名,基类,名称空间
            print(kwargs) #空的 
            print("new run")
            # return super().__new__(cls,*args,**kwargs)
            obj = type.__new__(cls,*args,**kwargs)
            return obj
        def __init__(self,a,b,c):
            super().__init__(a,b,c)
            print("init run")
    class A(metaclass=Meta):
        pass
    print(A)
    View Code

    三.单例

    单例:指的是一个类产生一个对象

    使用单例是为了节省 资源

    class Singel(type) :
    
        def __call__(self, *args, **kwargs):
    
            if hasattr(self,'obj') :
                return getattr(self,'obj')
    
            obj = super().__call__(*args,**kwargs)
            print(obj)
            print('new')
            self.obj = obj
            return obj
    
    class Student(metaclass=Singel):
        def __init__(self,name):
            self.name = name
    
    
    stu = Student('jack')
    print(stu)
    stu = Student('jack')
    print(stu)
    stu = Student('jack')
    print(stu)
    View Code
  • 相关阅读:
    四、分配swap分区
    三、fdisk分区
    二、文件系统常用命令
    一、回顾分区和文件系统
    三、文件系统属性chattr权限&系统命令sudo权限
    2、开发环境搭建
    1、基本概念
    SSH服务
    CentOS 7安装启动vsftpd服务
    01.HTML 5与HTML4的区别
  • 原文地址:https://www.cnblogs.com/Cpsyche/p/11273221.html
Copyright © 2020-2023  润新知