首页 > 其他 > 详细

反射函数与元类

时间:2019-07-30 23:05:39      阅读:69      评论:0      收藏:0      [点我收藏+]

一.反射函数

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

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

 

四种内置方法:getattr   setattr  delattr  hassttr

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

 

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

 

delattr:为对象添加新的属性

 

hasattr:从对象中删除属性

技术分享图片
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

 

反射函数与元类

原文:https://www.cnblogs.com/Cpsyche/p/11273221.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!