• Day 27 类的进阶-反射


    11. __new__ 和 __metaclass__
    
    阅读以下代码:
    
    1
    2
    3
    4
    5
    6
    class Foo(object):
     
        def __init__(self):
            pass
     
    obj = Foo()   # obj是通过Foo类实例化的对象
    上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。
    
    如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。
    
    1
    2
    print type(obj) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建
    print type(Foo) # 输出:<type 'type'>              表示,Foo类对象由 type 类创建
    所以,obj对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。
    

      

    一、isinstance and issubclass

    isinstance(obj,cls)检查是否obj是否是类cls的对象

    #对象与类的关系
    #判断第一个参数是否是第二个参数的实例
    class A:pass
    class B(A):pass
    class C(B):pass
    c = B()
    print(isinstance(c,A)) #包含继承关系的判断.
    #结果 True

    issubclass (sub,super)检查sub类是否是super类的派生类
    #类与类之间的关系

    print(issubclass(C,B))
    #结果为True

    二 、 反射

    1.什么是反射
    只要是指程序可以访问、检测和修改他本身状态或者
    或行为的一种能力。
    2. python面向对象中的反射:通过字符串的形式操作对象相关的属性,python中的一切事物都是对象(都可以使用反射)
    四个可以实现自省的函数

    下列方法适用于类和对象

    hasattr(判断某一个变量是否能够调用一个名字,返回True或者False)
    class Foo:
    f ='类的静态变量'
    def __init__(self,name,age):
    self.name =name
    self.age =age
    def say_hi(self):
    print("hi,%s " %self.name)

    obj= Foo('egon',73)

    # #检测是否还有某种属性
    # print(hasattr(obj, 'name'))
    # print(hasattr(obj,'sya_hi'))
    # 打印结果:
    # True# False

    getattr (直接获取一个变量中的名字的值)


    #获取属性
    n= getattr(obj,'name')
    print(n)
    #结果:egon

    func =getattr(obj,'say_hi')
    func()
    #结果:hi, egon
    # print(getattr(obj,'aaaaa',))#报错。


    setattr (为一个变量增加或者修改一个属性)
    # 设置属性
    setattr(obj,'sb',1)
    # setattr(obj,'show_name',lambda self:self.name+'sb')
    print(obj.__dict__)
    # 打印结果:{'name': 'egon', 'age': 73, 'sb': 1}

    # print(obj.show_name(obj))


    delattr (删除一个变量中的属性或者方法)

    delattr(obj,"age")
    # delattr(obj,"show_name")
    print(obj.__dict__)
    #输出结果{'name': 'egon', 'sb': 1}

    a.b 的形式
    d ={'k':'v'}
    print(getattr(d,"key")


    三、包的反射

    def wahaha(self, a, b):
    print(a, b)

    setattr(hei,'func',wahaha)
    hei.func(hei,1,2)


    # f = open() #文件操作对象
    # f.read() #文件对象,read 方法.
    # 模块名.函数名

    #此py文件名为my_moudle
    money = 1000
    def qqxing():
    print('qqxing')


    #另外一个sheet
    import my_module
    # print(my_module.money)#结果为1000

    #或者如下
    print(getattr(my_module,'money'))#输出结果1000
    getattr(my_module,'qqxing')()#结果为qqxing
    def sww():
        print('爽歪歪')
    count = 0
    import sys
    import my_module
    print(sys.modules[__name__]) #一定是当前的名字aaa.py
    #结果为 : <module '__main__' from 'D:/parcharm/12/Day24/1.py'>
    print(sys.modules['__main__'])# 不确定的。 <module '__main__' from 'D:/parcharm/12/Day24/1.py'>
    print(getattr(sys.modules[__name__],'count')) #结果为 0
    getattr(sys.modules[__name__],'sww')() #结果为爽歪歪
    print(sys.modules[__name__]) #输出结果:<module '__main__' from 'D:/parcharm/12/Day24/1.py'>
    print(sys.modules['my_module'])
    # 结果 <module 'my_module' from 'D:\parcharm\my_module.py'>
    print(my_module) 
    #结果<module 'my_module' from 'D:\parcharm\my_module.py'>


    # 反射类中的名字
    # getattr(类名,'静态属性')
    # getattr(类名,'类方法')()
    # getattr(类名,'静态方法')()

    # 反射对象中的名字
    # getattr(对象名,'对象属性')
    # getattr(对象名,'方法名')()

    # 反射模块中的名字
    # import 模块名
    # getattr(模块名,'模块中的变量')
    # getattr(模块名,'模块中的函数')()
    # getattr(模块名,'模块中的类名')

    # 反射当前模块中的名字
    # import sys
    # getattr(sys.modules[__name__],'变量')
    # getattr(sys.modules[__name__],'函数')()
    # getattr(sys.modules[__name__],'类名')

    # sys.modules[__name__]
    # import sys
    # print(sys.modules[__name__]) # 所有导入过的模块
    # {'字符串数据类型的模块名':模块的内存地址}
    # {'__main__':当前模块的内存地址}




    # 怎么反射类 ?
    class Student:
    def __init__(self,name,age):
    self.name = name
    self.age = age
    def show_student(self):
    for key in self.__dict__:
    print(key,self.__dict__[key])

    class Teacher:
    def __init__(self, name, age):
    self.name = name
    self.age = age

    def show_teacher(self):
    for key in self.__dict__:
    print(key, self.__dict__[key])

    class Manager:
    def __init__(self, name, age):
    self.name = name
    self.age = age

    def show_manager(self):
    for key in self.__dict__:
    print(key, self.__dict__[key])
    # hei = Student('小黑',18)
    import sys
    main = sys.modules[__name__]
    # import my_moudle
    # cls = getattr(my_moudle,'Student')
    # hei = cls('小黑',18)
    # print(hei,hei.__dict__)

    # 'Manager' 'Teacher' 'Student'
    # 获取字符串数据类型的类名
    cls_name = input('>>>')

    # 根据输入反射找到具体的类
    if hasattr(main,cls_name):
    cls = getattr(main,cls_name)

    # 实例化对象
    alex = cls('alex',81)
    print(type(alex))
    # 展示这个对象中的所有方法
    for i in alex.__dict__:
    print(i,alex.__dict__[i])

    # 用反射的知识 实现
    # 写一个人类,这个人类 没有任何属性 实例化这个类 然后根据你的姓名和年龄为这个对象添加属性 (基础)
    # 登录成功之后自动创建和用户身份匹配的类的对象 (提高)

  • 相关阅读:
    ubuntu下安装pip
    [算法]获得最短路径的Floyd与Dijkstra算法
    win2003终端服务授权
    Cookie 读取,解决中文乱码
    MOSS自动备份
    MOSS 开发收藏
    Private Protect Partial Internal Public 区别
    怎么设置OUTLOOK接收邮件时,网站邮箱的原始文件也保存着?
    正则表达式实战
    SQL Server 2005 数据库用户和登录帐户设置关链
  • 原文地址:https://www.cnblogs.com/mengbin0546/p/8549519.html
Copyright © 2020-2023  润新知