zoukankan      html  css  js  c++  java
  • python3 反射

    hasattr(obj, str) 判断obj对象中是否有str成员

    getattr(obj, str) 从obj对象中获取str成员

    setattr(obj, str, value) 把obj对象中的str设置为value

    delattr(obj, str) 从obj对象中删除str成员

    以上方法都是在内存中执行的,不会影响源代码

    先看下hasattr和getattr的使用

    # master.py
    name = "lily"
    
    
    def func1():
        print("我是func1")
    
    
    def func2():
        print("我是func2")
    
    
    def func3():
        print("我是func3")
    
    
    class Person:
        pass
    # test反射.py
    from types import FunctionType
    import master
    
    
    while 1:
        inp = input("请输入你要执行的方法:").strip()
        if hasattr(master, inp):
            fn = getattr(master, inp)
            if callable(fn):  # 同 if isinstance(fn, FunctionType):
                fn()
            else:
                print(fn)
        else:
            print("输入的变量名不存在")

    执行test反射.py的结果:

    请输入你要执行的方法:name
    lily
    请输入你要执行的方法:func1
    我是func1
    请输入你要执行的方法:func2
    我是func2
    请输入你要执行的方法:aa
    输入的变量名不存在
    请输入你要执行的方法:Person
    <class 'master.Person'>
    请输入你要执行的方法:

    接下来看下setattr的使用(只是在内存中修改,对源代码无影响)

    # setattr实例.py
    import master
    
    fn = lambda: print("我是修改后的func1")  # 无参数无返回值的函数
    # def fn():  # 同fn = lambda: print("我是修改后的func1")
    #     print("我是修改后的func1")
    master.func1()
    setattr(master, "func1", fn)
    master.func1()

    执行setattr实例.py的结果:

    我是func1
    我是修改后的func1

     delattr的使用(只是在内存中删除,对源代码无影响)

    import master
    
    
    print(master.func1)
    delattr(master, "func1")
    print(master.func1)  # AttributeError: module 'master' has no attribute 'func1'

    执行结果:

    Traceback (most recent call last):
      File "G:/python28/code/python-28/day07/反射/delattr的操作.py", line 6, in <module>
        print(master.func1)
    AttributeError: module 'master' has no attribute 'func1'
    <function func1 at 0x00000000029779D8>

    一定要注意反射在类中的使用,不能建议使用getattr(类名, 方法名)

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def func(self):
            print(f"我是func 我的名字是{self.name}")
    
    
    p = Person("lily", 18)
    f1 = getattr(p, "func")
    f1()
    f2 = getattr(Person, "func")  
    # f2()  # 报错TypeError: func() missing 1 required positional argument: 'self'
    f2(p)

    执行结果:

    我是func 我的名字是lily
    我是func 我的名字是lily

    总结:

      fn = getattr(obj, str1) 相当于fn = obj.str1

      fn() 相当于obj.str1()

      f1 = getattr(p, "func") 相当于f1 = p.func

      f1() 相当于p.func() 因为 func是实例方法,所以对象调用实例方法是正常的。如果这里看着费劲或者看不懂,请先 https://www.cnblogs.com/lilyxiaoyy/p/11988523.html

      f2 = getattr(Person, "func") 相当于 f2 = Person.func

      f2() 相当于Pereson.func() 这里肯定是报错的,因为实例方法的一个参数默认是对象self

      f2(p) 相当于Person.func(p) 手动把对象p传递给实例方法的第一个参数,不推荐使用类名调用实例方法。

    反射在类中的使用

    # 反射在类中的使用.py
    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def func(self):
            print(f"我是func 我的名字是{self.name}")
    
    
    p = Person("lily", 18)
    
    if hasattr(p, "func"):  # attribute 判断p对象中是否有func属性
        fn = getattr(p, "func")  # 从p对象中获取func属性
        if callable(fn):  # 判断是否可以被调用  + ()
            fn()
    
    # delattr(p, "name")  # 删除p对象中的name属性
    # print(p.name)
    
    p2 = Person("lucy", 16)
    print(p2.name)
    
    setattr(p, "address", "北京市八大胡同")  # 给p对象设置address属性,值为北京市八大胡同
    print(p.address)  # 北京市八大胡同
    
    setattr(p, "func2", lambda: print("我是func2"))
    p.func2()

     执行结果:

    我是func 我的名字是lily
    lucy
    北京市八大胡同
    我是func2
  • 相关阅读:
    一年来把自己从学.Net到用.Net,收集的资料共享出来B/s中的存储过程(二)
    收集的.Net文章(十五)ASP.NET 2.0 Caching For performance
    收集的.Net文章(十六)SQL Server日期计算
    P.V操作原语和信号量
    2004年2008年系分论文题目整理,考SA的可以看一下
    2010年个人总结
    MASM,NASM和AT&T汇编格式备注
    Unity Application Block 学习笔记之一使用配置文件
    Javascript 学习笔记之String类测试
    javascript学习笔记之Object类型测试
  • 原文地址:https://www.cnblogs.com/lilyxiaoyy/p/10917151.html
Copyright © 2011-2022 走看看