zoukankan      html  css  js  c++  java
  • Python学习笔记之Python对象反射、类反射、模块反射

    反射

    python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

    反射机制就是在运行时,动态的确定对象的类型,并可以通过字符串调用对象属性、方法、导入模块,是一种基于字符串的事件驱动。

    解释型语言:程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次。因此效率比较低。相对于编译型语言存在的,源代码不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。比如Python/JavaScript / Perl /Shell等都是解释型语言。

    python是一门解释型语言,因此对于反射机制支持很好。在python中支持反射机制的函数有getattr()、setattr()、delattr()、exec()、eval()、__import__,这些函数都可以执行字符串。

    eval

    计算指定表达式的值。它只能执行单个表达式,而不能是复杂的代码逻辑。而且不能是赋值表达式。 单个表达式

    a = "12 + 43"
    b = eval(a)
    print(b)#55

    exec

    执行复杂表达式,返回值永远都是None

    b = exec("aa = 21")
    print(b)      # None,exec返回值为None
    print(aa)    # 21,exec执行了赋值语句,并定义了aa变量

    执行复杂语句

    a = '''ret = []
    for i in range(10):
        ret.append(i)'''
    exec(a)
    print(ret)   # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    导入模块

    config.py

    KEYWORD = 123
    # 导入模块
    exec("import config")
    print(config.KEYWORD)
    
    # 动态创建类
    class Base:
        def __init__(self):
            print("Base")
    
    a = "Base"
    exec(a+"()")

    导入模块这个功能就非常屌了,这样我们就可以动态的创建各种模块类。

    eval()函数和exec()函数的区别: eval()函数只能计算单个表达式的值,而exec()函数可以动态运行代码段。 eval()函数可以有返回值,而exec()函数返回值永远为None。

    再看一下下面的例子:

    class Base:
        def __init__(self):
            print("Base")
    
        def test(self):
            print("test")
            return "Base::test"
    
    a = "Base"
    b = eval(a+"()")
    # b = eval("b.test()")
    b = exec("b.test()")
    print(b)

    输出: test Base::test 如果不需要获取返回值,那么可以使用exec,exec("a.test()"),输出:test

    虽然我们可以使用eval和exec来执行以上代码,但是这种方式有一个缺陷,假如这个属性是不存在的,那么这种调用就会报错。那么做好的方式是什么呢?先判断属性是否存在,如果存在就调用,不存在就不调用,python为我们提供了一套方法:hasattr、getattr、setattr、delattr

    一、getattr

    对象获取

    # coding:utf-8
    class Manager:
        role = "管理员"
        def __init__(self,name,sex,phone,mail):
            self.name = name
            self.sex = sex
            self.phone = phone
            self.mail = mail
    
        def createClass(self):
            print("create class")
    
        def createTeacher(self):
            print("createTeacher")
    
        def createStu(self):
            print("createStu")
    
    manager = Manager("safly","",123456,123456)
    
    
    print("---对象获取对象方法-----")
    f = getattr(manager,"createClass")
    f()
    
    print("---对象获取对象属性-----")
    name = getattr(manager,"name")
    print(name)
    
    print("---对象获取类属性-----")
    role = getattr(manager,"role")
    print(role)
    
    print("---对象获取类属性(可以设置默认值)-----")
    import logging
    if  hasattr(manager,"role1"):
        role = getattr(manager,"role1","roleDefault")
        print(role)
    else:
        logging.warn("没有role属性")
        role = getattr(manager, "role1", "roleDefault")
        print(role)

    运行结果:

    ---对象获取对象方法-----
    create class
    ---对象获取对象属性-----
    safly
    ---对象获取类属性-----
    管理员
    ---对象获取类属性(可以设置默认值)-----
    WARNING:root:没有role属性
    roleDefault

    类获取

    #coding=utf-8
    class Manager:
        role = "管理员"
        def createClass(self):
            print("create class")
    
        def createStu(self):
            print("createStu")
    
    m = Manager()
    
    f = getattr(Manager,"createClass")
    f(Manager())
    
    f = getattr(Manager,"createClass")
    f(m)
    
    role = getattr(Manager,"createStu")
    role(m)
    
    #对象获取类属性
    role = getattr(Manager,"role")
    print(role)

    Traceback (most recent call last):
      File "E:/program/ljt_test/test/test2.py", line 13, in <module>
       f(Manager)#参数需要是类实例,忘了写括号。
    TypeError: unbound method createClass() must be called with Manager instance as first argument (got classobj instance instead)

    运行输出:

    create class
    create class
    createStu
    管理员

    二、setattr

    设置类属性、方法

    class Manager:
        role = "管理员"
        def __init__(self,name,sex,phone,mail):
            self.name = name
            self.sex = sex
            self.phone = phone
            self.mail = mail
    
        def createClass(self):
            print("create class")
    
    manager = Manager("safly","",123456,123456)
    
    print("----设置类属性------")
    setattr(Manager,"country","china")
    print(Manager.country)
    
    print("----删除类属性------")
    delattr(Manager,"country")
    # #删除报错
    # print(Manager.country)
    print("----设置类方法------")
    @staticmethod
    def Method(cls,parm):
        print u"我是被绑定的class之外的方法parm--",parm
    
    setattr(Manager,"Method",Method)
    Manager.Method(Manager,1)

    运行结果:

    ----设置类属性------
    china
    ----删除类属性------
    ----设置类方法------
    我是被绑定的class之外的方法parm-- 1

    设置对象属性、方法

    #coding=utf-8
    class Manager:
        role = "管理员"
        def __init__(self,name,sex,phone,mail):
            self.name = name
            self.sex = sex
            self.phone = phone
            self.mail = mail
    
        def createClass(self):
            print("create class")
    
        def createTeacher(self):
            print("createTeacher")
    
        def createStu(self):
            print("createStu")
    
    
    manager = Manager("safly","",123456,123456)
    
    print("----设置对象属性------")
    setattr(manager,"age",20)
    print(manager.age)
    
    print("----删除对象属性------")
    delattr(manager,"age")
    # 'Manager' object has no attribute 'age'
    # print(manager.age)
    
    print("---对象不能删除类属性---")
    setattr(Manager,"country","china")
    print(Manager.country)
    # delattr(manager,"country")
    # print(Manager.country)
    
    print("----设置对象方法------")
    def create_course(self):
        print('创建了一个课程')
    
    setattr(manager,'create_course',create_course)
    manager.create_course(manager)
    
    def create_grade():
        print('创建了一个班级')
    setattr(manager,'create_grade',create_grade)
    
    manager.create_grade()
    print manager.__dict__
    exit(0)

    运行输出结果:

    ----设置对象属性------
    20
    ----删除对象属性------
    ---对象不能删除类属性---
    china
    ----设置对象方法------
    创建了一个课程
    创建了一个班级
    {'name': 'safly', 'create_course': <function create_course at 0x022F6D30>, 'create_grade': <function create_grade at 0x023744F0>, 'sex': 'xe7x94xb7', 'phone': 123456, 'mail': 123456}

    三、模块反射

    创建一个模块mokuai.py

    a = 1
    def method(rag):
        print(rag)
        return "666"

    然后在python.py中导入以上模块

    import mokuai
    print(getattr(mokuai,"a"))
    method = getattr(mokuai,"method")
    ret = method(8888)
    print(ret)

    输出如下:

    1
    8888
    666
    
    

    四、反射本模块函数、变量

    #coding=utf-8
    aa = 11
    def method():
        print("---method---")
    import sys
    
    print(sys.modules[__name__])
    print(getattr(sys.modules[__name__],"aa"))
    f = getattr(sys.modules[__name__],"method")
    f()

    输出如下:

    <module '__main__' from 'E:/program/ljt_test/test/test2.py'>
    11
    ---method---

    三、hasattr

     hasattr(object, name)

    判断object对象中是否存在name属性,当然对于python的对象而言,属性包含变量和方法;有则返回True,没有则返回False;需要注意的是name参数是string类型,所以不管是要判断变量还是方法,其名称都以字符串形式传参;getattr和setattr也同样;

    #coding=utf-8
    class A():
    name = 'python'
    def func(self):
    return 'A()类的方法func()'

    print hasattr(A, 'name')

    print hasattr(A, 'age')

    print hasattr(A, 'func')

    运行结果:

    True
    False
    True

     https://cloud.tencent.com/developer/article/1447119

    https://cloud.tencent.com/developer/article/1156663

    https://www.cnblogs.com/zanjiahaoge666/p/7475225.html

  • 相关阅读:
    更改文件默认打开方式
    python数据分析高频词提取,pyecharts词云制作并保存
    pyecharts V1.x版本使用Map绘制地图修改主题背景色等
    设置随机请求头和使用代理
    【重学前端】JS基础-原型和原型链
    【重学前端】JS基础-变量和类型
    Bootstrap blog整页制作
    拉勾网 移动端流式布局与rem布局整页制作
    PC端管理后台整页制作
    QQ飞车官方首页(部分)制作
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4337059.html
Copyright © 2011-2022 走看看