Python面向对象 | 反射

Posted summer-skr--blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面向对象 | 反射相关的知识,希望对你有一定的参考价值。

 

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

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


四个内置函数:

hasattr(obj, attr): 
  这个方法用于检查obj是否有一个名为attr的值的属性,返回一个布尔值。

getattr(obj, attr): 
  调用这个方法将返回obj中名为attr值的属性的值,例如如果attr为‘bar‘,则返回obj.bar。
setattr(obj, attr, val): 
  调用这个方法将给obj的名为attr的值的属性赋值为val。例如如果attr为‘bar‘,则相当于obj.bar = val
delattr(obj, name)
  该函数删除该obj的一个由string指定的属性。delattr(x, ‘foobar‘)=del x.foobar

 

对实例化对象的反射

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(Tony,18)

#检测是否含有某属性
print(hasattr(obj,name))                  # True
print(hasattr(obj,say_hi))                # True

#获取属性
print(getattr(obj,name))                  # Tony
print(getattr(obj,say_hi))           # <bound method Foo.say_hi of <__main__.Foo object at 0x00000219B4CF6688>>
print(getattr(obj,aaaaaaaa,不存在啊))   # 不存在啊.如果不设置就会报错

#设置属性
setattr(obj,John,True)
setattr(obj,show_name,lambda self:self.name+)
print(obj.__dict__)     # {‘name‘: ‘Tony‘, ‘age‘: 18, ‘John‘: True, ‘show_name‘: <function <lambda> at 0x000001E56C6AC048>}
print(obj.show_name(obj))                   # Tony君

#删除属性
delattr(obj,age)
delattr(obj,show_name)
# delattr(obj,‘show_name111‘    )            #不存在,则报错
print(obj.__dict__)                         # {‘name‘: ‘Tony‘, ‘John‘: True}

 

反射

class Foo(object):
    staticField = "old boy"

    def __init__(self):
        self.name = wupeiqi

    def func(self):
        return func

    @staticmethod
    def bar():
        return bar


print (getattr(Foo, staticField))        # 注意第二个参数无论是静态属性、对象属性、方法,都要加单引号‘’
print (geattr(Foo, func))
print (getattr(Foo, bar))

 

当前模块的反射

import time          # 一个py文件就是一个模块
time.time()

if hasattr(time,time):
    print(time.time)
    print(getattr(time,time)())

‘‘‘
执行输出:
<built-in function time>
1569572942.545881
‘‘‘

 

import sys
def s1():
    print(s1)
def s2():
    print(s2)

current_module = sys.modules[__name__]
print(current_module)
print(hasattr(current_module, s1))
print(getattr(current_module, s2))

‘‘‘
执行输出:
<module ‘__main__‘ from ‘C:/Users/Administrator/Desktop/temp/test.py‘>
True
<function s2 at 0x0000026BFDF98048>
‘‘‘

 

 

其他模块的反射

"""
程序目录:
    module.py
    test.py
"""


# 模块module.py中的代码
class A:
    name = "module"

    def func():
        print(我是module模块的func)


# test.py中的代码
import module

# 方法一:
clas = getattr(module, A)
print(clas.name)                    # module

# 方法二:
print(getattr(module.A, name))    # module
getattr(module.A, func)()         # 我是module模块的func

 

假设有一个文件名userinfo,需要重命名

# 第一种:常规办法
import os
os.rename(userinfo,user)

# 第二种:使用反射
import os
getattr(os,rename)(userinfo,user)      # getattr(os,‘rename‘) 相当于os.rename

 

总结:

1. 类使用类命名空间中的名字
  getattr(类名,‘名字‘)

2. 对象使用对象能用的方法和属性
  getattr(对象名,‘名字‘)

3. 从自己所在的模块中使用自己名字
  import sys

  getattr(sys.modules[‘__main__‘],名字)

4. 模块使用模块中的名字
  导入模块

  getattr(模块名,‘名字‘)

import os ;
getattr(os,rename)(user,user_info)

以上是关于Python面向对象 | 反射的主要内容,如果未能解决你的问题,请参考以下文章

Python之面向对象-反射

Python面向对象 | 反射

Python面向对象反射,双下方法

Python面向对象之反射,双下方法

python面向对象的反射

Python基础-week06 面向对象编程进阶