1、介绍

  反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

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

  对类进行反射操作,执行的结果是查询或修改类的属性
  对实例化对象进行反射操作,执行的结果是查询或修改实例化对象的属性

2、四个可以实现自省的函数

hasattr(对象名,'属性名') #判断对象中是否存在该属性
getattr(对象名,'属性名', 默认值可选) #获取对象中的该属性的值,可以添加默认值
setattr(对象名,'属性名', vlaue) #设置对象中的该属性名的值为vlaue
delattr(对象名,'属性名') #删除对象中的该属性

3、例子

1:对象示例(一切皆对象,类本身也是一个对象)

class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def say_hi(self):
        print('hi,%s'%self.name)
        
#检测是否含有某属性
obj = Foo('Tom', 25)
print(hasattr(obj, 'name'))
# True
print(hasattr(obj, 'say_hi'))
# True

#获取属性
name = getattr(obj, 'name')
print(name)
# Tom
print(getattr(obj, 'name1', '不存在'))
# 不存在   #如果不加默认值就会报错
func = getattr(obj, 'say_hi')
if func:
    func()
# hi, Tom

#设置属性
setattr(obj, 'sex', 'man')
print(obj.sex)
# man

#删除属性
delattr(obj, 'sex')
print(obj.__dict__)
{'name': 'Tom', 'age': 25}
delattr(obj, 'name1')
#不存在,则报错,AttributeError: name1

 

例子2:对类的示例

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'))
#old boy
ret1 = getattr(Foo, 'func')
print(ret1(1))
#func 传入参数1,并执行ret1获取的方法
print(getattr(Foo, 'func')(1))
#func 
print(getattr(Foo, 'bar')())
#bar

 

例子3:对当前模块的示例

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

def s2():
    print('s2')

this_module = sys.modules[__name__]

print(hasattr(this_module, 's1'))
# True
getattr(this_module, 's2')()
# s2

 

例子4:其他模块的示例

#一个模块中的代码
def test():
    print('from the test')
"""
程序目录:
    module_test.py
    index.py
 
当前文件:
    index.py
"""

# 另一个模块中的代码
fs.py文件有如下代码 
n1 = 'Tom'
def func():
    print(666)

class A:
    name = 'Mike'
    def func2(self):
        print('--------IN FUNC2')

test.py文件有如下代码:
import fs
print(getattr(fs, 'n1'))
# Tom 可以从导入的fs模块中获取到n1属性
ret1 = getattr(fs, 'func')
ret1()
# 666  可以从导入的fs模块中获取func方法并执行

ret2 = getattr(fs, 'A')
print(ret2.name)
# Mike  可以从导入的fs模块中获取A类,打印A类的name属性

print(getattr(fs.A, 'name'))
# Mike 可以从导入的fs模块中的A属性中获取name属性并执行

ret3 = getattr(fs.A, 'func2')(1)
# --------IN FUNC2  获取func2方法,并传入参数1执行

 

posted on 2018-11-20 09:12  longfei2021  阅读(116)  评论(0编辑  收藏  举报