Python面向对象之反射

一、反射的基本概念

反射:可以用字符串的方式去访问对象的属性,调用对象的方法(但是不能去访问方法),Python中一切皆对象,都可以使用反射。

反射有四种方法:

hasattr(obj, str) #判断一个对象是否有str属性或者string方法,有就返回True,没有就返回False

getattr(obj, str) #获取对象的属性或者方法,如果存在则打印出来,getattr和hasattr配套使用
#注意:如果返回的是对象的方法,那么返回的是对象的内存地址,如果需要运行这个方法,可以在后面添加一对()

setattr(obj, str, value) #把obj中的str成员设置成value,注意,这里的value可以是值,也可以是函数或者方法

delattr(obj,str) #把obj中的str成员删除掉

注意:以上操作都是在内存中进行的,并不会影响你的源代码

二、反射示例

示例1:

class Foo:
    def __init__(self):
        self.name = 'egon'
        self.age = 51
    def func(self):
        print("hello")

egg = Foo()
setattr(egg, 'gender', 'male')
print(egg.gender)
print(egg.__dict__)


def show_name(self):
    print(self.name + 'sb')
setattr(egg, 'show_name', show_name)
egg.show_name(egg)
show_name(egg)

delattr(egg, 'name')
print(egg.__dict__)

# 打印结果:
male
{'name': 'egon', 'age': 51, 'gender': 'male'}
egonsb
egonsb
{'age': 51, 'gender': 'male', 'show_name': <function show_name at 0x101fabe18>}

示例2:

# 反射示例2
class Foo:
    pass

f = Foo()

print(hasattr(f, 'chi'))  # False

setattr(f, 'chi', '123')
print(f.chi)  # 123
print(f.__dict__)  # {'chi': '123'}

setattr(f, 'chi', lambda x: x + 1)
print(f.chi(3))  # 4
print(f.chi)  # 注意:此时的chi既不是静态方法也不是实例方法,更不是类方法,就相当于你在类中写了个 self.chi = lambda 是一样的
print(f.__dict__)  # {'chi': <function <lambda> at 0x101eabe18>}

delattr(f, 'chi')
print(hasattr(f, 'chi'))  # False

# 打印结果:
False
123
{'chi': '123'}
4
<function <lambda> at 0x101eabe18>
{'chi': <function <lambda> at 0x101eabe18>}
False

三、反射的应用

1.对象应用反射

 class Foo:
 2     def __init__(self):
 3         self.name = 'egon'
 4         self.age = 51
 5     def func(self):
 6         print('hello')
 7 egg = Foo()
 8 print(hasattr(egg,'name'))  #先判断name在egg里面存在不存在
 9 print(getattr(egg,'name')) #如果为True它才去得到
10 print(hasattr(egg,'func'))
11 print(getattr(egg,'func'))  #得到的是地址
12 # getattr(egg,'func')()  #在这里加括号才能得到,因为func是方法
13 if hasattr(egg,'func'):
14     getattr(egg,'func')()
15 else:
16     print('没找到')

2.类应用反射

 1 class Foo:
 2     f = 123
 3     @classmethod
 4     def class_method_dome(cls):
 5         print('class_method_dome')
 6 
 7     @staticmethod
 8     def static_method_dome():
 9         print('static_method_dome')
10 print(hasattr(Foo,'class_method_dome'))
11 method = getattr(Foo,'class_method_dome')
12 method()
13 print('------------')
14 print(hasattr(Foo,'static_method_dome'))
15 method1 = getattr(Foo,'static_method_dome')
16 method1()

3.模块应用反射

模块的应用又分为导入其他模块反射和在本模块中反射

  • 到入其他模块反射
 # 1.导入其他模块引用
2 import mymodule
3 print(hasattr(mymodule,'test'))
4 getattr(mymodule,'test')()
5 
6 # # 这里的getattr(mymodule,'test')()这一句相当于
7 # p = getattr(mymodule,'test')
8 # p()
  • 在本模块中应用反射
1 # 2.在本模块中应用反射
2 def demo1():
3     print('wwww')
4 import sys
5 # print(sys.modules)
6 module_obj = sys.modules[__name__]  #相当于'__main__'
7 print(module_obj)
8 print(hasattr(module_obj,'demo1'))
9 getattr(module_obj,'demo1')()

导入自己的模块的一个简单小例子:

 1 # 举例
 2 def 注册():
 3     print('regiester')
 4 def 登录():
 5     print('login')
 6 def 购物():
 7     pass
 8 print('注册,登录,购物')
 9 ret = input('请输入你要做的操作:')
10 import sys
11 my_module = sys.modules[__name__]  #利用sys模块导入一个自己的模块
12 if hasattr(my_module,ret):
13     getattr(my_module,ret)()

4.其他

db.mysql

class MySQlHelper(object):
    print('MySQlHelper1111111')
    def fetchone(self):
        print('你好')

db.pool

class PoolHelper(object):
    print('PoolHelper')

settings.py

DB_PATH = 'db.mysql.MySQlHelper'

#吧字符串切割
module_name,cls_name = DB_PATH.rsplit('.',maxsplit=1)
# print(module_name,cls_name)  #db.mysql    MySQlHelper
#导入模块
# from db.mysql import MySQlHelper
import importlib
moudel_obj = importlib.import_module(module_name)
print(moudel_obj,type(moudel_obj))
#导入模块中的类
cls = getattr(moudel_obj,cls_name)
print(cls)
#对类进行实例化
obj = cls()
obj.fetchone()
# getattr()
原文地址:https://www.cnblogs.com/russellyoung/p/python-mian-xiang-dui-xiang-zhi-fan-she.html