python反射机制

python反射机制

一、 应用场景

  1. 根据不同的场景运行不同的函数,可以将这种写入配置中,读取配置,运行对应的函数,这个时候获取的函数为字符串,如何运行该字符串呢?

二、 反射的定义

  1. 反射就是通过字符串的形式,导入模块;反射就是通过字符串的形式,导入模块;
  2. 通过字符串的形式,去模块寻找指定函数,并执行。
  3. 利用字符串的形式去对象中操作属性或者函数利用字符串的形式去对象中操作属性或者函数
  4. 一种基于字符串的事件驱动一种基于字符串的事件驱动

三、 类中实现

  1. getattr(object, filed, default)
    从对象object中获取field对象(可能为属性或者方法),如果不存在,则返回默认值default

  2. hasattr(object, field)
    判断对象object中是否含有field对象,返回True/False

  3. setattr(object, field, value)**
    object.field = value (赋值操作)

  4. delattr(object, field)**
    删除对象的某个属性
    上述四个函数中的filed均为字符串类型,用来表示对象的一个属性名或者方法名

    # coding=utf8
    class A(object):
    
    	static_name = 'static_name'    # 静态属性
    	def __init__(self):
    		self.name = 'name '  # 属性名
    
    	def func_name(self, name=''):
    		self.name = name
    		print name
    
    	@staticmethod
    	def static_func_name(self, name='11'):
    		static_name = name
    		print static_name
    
    if __name__ == '__main__':
    	print(hasattr(A, 'name'))                   # False
    	print(hasattr(A(), 'name'))					# True
    	print(hasattr(A, 'static_name'))			# True
    	print(hasattr(A(), 'static_name'))			# True
    	print(hasattr(A, 'name'))					# False
    	print(hasattr(A(), 'name'))					# True
    	print(hasattr(A, 'static_func_name'))		# True
    	print(hasattr(A(), 'static_func_name'))		# True
    

    通过这个,也可以清晰的看出来类属性对象属性的差别

    if __name__ == '__main__':
    	print(getattr(A, 'static_name', 'default_name'))					# static_name
    	print(getattr(A, 'name', 'default_name'))							# default_name 这个没有取到,所以用了默认值,类属性和对象属性
    	print(getattr(A(), 'name', 'default_name'))							# name
    	print(getattr(A(), 'error_name', 'default_name'))					# 'default_name' 这个没有渠道
    
    	getattr(A, 'static_func_name', 'f')(name='A.static_func_name()')	# A.static_func_name()
    	getattr(A(), 'func_name', 'f')(name='A.func_name()')				#  A.func_name()
    
    	print(getattr(A(), 'func_name', None))								# <bound method A.func_name of <__main__.A object at 0x10c2f4910>>
    	print(getattr(A, 'func_name', None))								# <unbound method A.func_name>  未找到的意思 相当于None值
    

    回到第一个应用场景

    1. 首先,我们可以定义一个类或者模块,在类中定义不同场景下执行的不同的函数
    2. 然后将该函数和场景写成配置,{“场景”: “配置”}
    3. 在不同的场景下,读取配置,首先使用hasattr判断该函数是否存在,然后使用getattr执行该函数
    4. 如果想,类也可以配置,不过,所有场景写在一个固定类里面,等以后添加新的场景的时候,会容易配置一些

四、 模块中实现

  1. 动态导入一个模块名
    import(‘module_name’)
  2. 导入模块下的子模块
    import(‘module_name’, fromlist = True)

五、 exec和eval

  1. exec(“print(‘hello’)”)
  2. eval(expression, globals=None, locals=None)
    官方文档:https://www.programiz.com/python-programming/methods/built-in/eval
    x = 1
    print(eval('x + 1'))
    
    不推荐使用eval,会有安全问题

六、 扩展

  1. 对象的内建函数或者方法http://www.cnblogs.com/huxi/archive/2011/01/02/1924317.html

    dir(A())
    返回A对象的函数和方法:
    ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'func_name', 'name', 'static_func_name', 'static_name']
    
    dir(A)
    ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'func_name', 'static_func_name', 'static_name']
    
    	A.__doc__     # 类的描述信息
    	A.__name__    # 类名
    	A.__dict__  # 包含了模块里可用的属性名-属性的字典;也就是可以使用模块名.属性名访问的对象。
    	A.__dict__ = {
    				'__module__': '__main__',
    				'static_name': 'static_name',
    				'__dict__': < attribute '__dict__' of 'A' objects > ,
    				'func_name': < function func_name at 0x10558e6e0 > ,
    				'static_func_name': < staticmethod object at 0x1055a4360 > ,
    				'__weakref__': < attribute '__weakref__' of 'A' objects > ,
    				'__doc__': '\n\t\xe7\xb1\xbb\xe6\x8f\x8f\xe8\xbf\xb0\n\t',
    				'__init__': < function __init__ at 0x10558e0c8 >
    		}
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值