首页 > 其他 > 详细

反射 元类

时间:2020-03-31 10:31:59      阅读:56      评论:0      收藏:0      [点我收藏+]
一.反射(reflect)
反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力
反射就是对字符串操作属性
四个内置函数:
1.hasattr(p,‘name‘) 判断某个对象是否存在某个属性
2.getattr(p,‘name‘,None) 从对象中取出属性,
第三个参数默认值,当属性不存在返回默然值
3.setattr(p,‘name‘,‘123‘) 为对象添加属性
4.delattr(p,‘name‘) 从对象中删除属性
代码:
技术分享图片
class Person:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def say_hi(self):
        print(hi my name is %s%self.name)

p = Person(jack,12)
print(p.name)

hasattr(p,name)
print(hasattr(p,name))

if hasattr(p,name):
    print(getattr(p, name, None))

print(getattr(p,name,None))
print(getattr(p,ane,None))  # None

# p.sb = ‘123‘
setattr(p,sb,123)
# print(p.sb)

delattr(p,id)
print(p.sb)
View Code

应用场景:
1.反射其实就是对属性的增删改查,但是如果直接使用内置的
__dict__来操作,语法繁琐,不好理解
2.另一个主要的原因:如果对象不是自己写的是另一方提供的,
我就必须判断这个对象是否满足要求,也就是是否是我需要的属性和方法
3.框架设计方式;
框架代码:
技术分享图片
import plugins
# 框架已经实现的部分
def run(plugins):
    while True:
        cmd = input(请输入指令:)
        if cmd == exit:
            break
        # 因为无法确定框架使用者是否传入正确的对象,所以需要使用反射来检测
        # 判断对象是否具备处里这个指令的方法
        if hasattr(plugins,cmd):
            # 取出对应方法
            func = getattr(plugins,cmd)
            func() # 执行方法处理指令
        else:
            print(该指令不受支持)
    print(see you na la)

# 创建一个插件对象,调用框架来使用它
wincmd = plugins.WinCMD()
# 框架之外的部分就有自定义对象来完成
linux = plugins.LinuxCMD()
run(linux)
View Code

 


二.元类
1.创建类的类,就叫做元类

万物皆为对象,类也是对象
对象是通过类实例化产生的,如果类也是对象的话,必然类对象也是有另一类实例化产生的

类用来管理对象,谁来管理类?我们用元类类管理类
默认情况下所有类的元类都是type

2.学习类的目的:
类用来管理对象,谁来管理类?我们用元类类管理类

就是需要对类对象进行一些限制:
想到了用初始化方法,我们只要知道类对象的类(元类),
覆盖其中init方法就能实现

列如:控制类名必须以大驼峰的方式书写
"""
只要继承了type,那么这个类就变成了一个元类
"""
# 定义一个元类
class MyType(type):
    def __init__(self,class_name,bases,dict):
        super().__init__(class_name,bases,dict)
        print(class_name,bases,dict)
        if not class_name.istitle():
            raise Exception(类名你不会鞋码:)

# 为Pig类指定元类为MyType
class Pig(metaclass=MyType):
    pass
# 为 Duck指定元类为MyType
class Duck(metaclass=MyType):
    pass

 


3.类的三个组成部分
1.类的名称(字符类型)
2.类的父类们(列表或元组)
3.类的名称空间(字典类型)

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

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

使用场景:
当你想要控制对象的创建过程时,就覆盖call方法
当你想要控制类的创建过程时,就覆盖call方法

注意: 一旦覆盖了call必须调用父类的call方法类产生对象
并返回这个对象

5.new方法
当你要创建类对象时,会首先执行元类中__new__方法,拿到一个空对象
然后会自动调用__init__来对这个类进行初始化操作

注意:如果你覆盖了该方法则必须保证,new方法必须有返回值,且必须是
对应的类对象

6.单列设计模式
单列:指的是一个类产生一个对象
用来解决某种固定问题的套路
MVC MTV
为什么要使用单列:就是为了节省资源,当一个类的所有属性全部相同时
则没有必要创建多个对象

反射 元类

原文:https://www.cnblogs.com/zhuangshenhao/p/11272509.html

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