第10章-序列的修改、散列和切片
反射
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力,在python中一切皆对象(类,实例,模块等等都是对象),那么我们就可以通过反射的形式操作对象相关的属性。
用字符串数据类型的变量名或者函数名来调用对应的属性
A.b getattr(A, 'b')
作用
1.实现可插拔机制
可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能
举个例子:
demo.py
class FanShe(object):
x = 1
def test1(self):
print('this is test1')
def test(self):
print("this is test")
其他文件调用:
import demo as tf
c = tf.FanShe
# 判断c对象中的test是否存在,存在即调用执行,不存在就执行其他逻辑代码
if hasattr(c, 'test'):
func = getattr(c, 'test')
print(func("hello"))
else:
print('不存在此方法')
print('处理其他的逻辑')
2.动态导入模块
demo/__init__.py
demo/work.py
work.py
def test():
print('this is test')
在外层想要调用这个work.py里面的test方法可以使用下面的方法:
M = __import__('demo.work')
print(M)
M.work.test()
# 可以写成这样
import importlib
M = importlib.import_module('demo.work')
print(M)
M.test()
Python反射方法
Python中的反射主要有下面几个方法:
1.hasattr(object,name)
判断对象中有没有一个name字符串对应的方法或属性
2.getattr(object, name, default=None)
获取对象name字符串属性的值,如果不存在返回default的值
3.setattr(object, key, value)
设置对象的key属性为value值,等同于object.key = value
4.delattr(object, name)
删除对象的name字符串属性
class Cat(object):
class_level = '贵族'
def __init__(self, name, type, speed, age):
self.name = name
self.type = type
self.speed = speed
self.age = age
def run(self):
print('%s岁的%s%s正在以%s的速度奔跑' %
(self.age, self.type, self.name, self.speed))
xiaohua = Cat('小花', '波斯猫', '10m/s', 10)
xiaohua.run() # 10岁的波斯猫小花正在以10m/s的速度奔跑
# hasattr(object, name) 判断对象中有没有一个name字符串对应的方法或属性
print(hasattr(xiaohua, 'name')) # 判断xiaohua有没有name的属性,返回True,说明小花有name的属性,
# 注意'name'一定要是字符串类型
print(hasattr(xiaohua, 'size')) # 返回False说明小花没有size的属性
# 2.getattr(object, name, default=None) 获取对象name字符串属性的值,
# 如果不存在返回default的值
print(getattr(xiaohua, 'speed', '20m/s')) # 10m/s
# 获取xiaohua的speed的属性,speed的属性存在
print(xiaohua.__dict__)
# {'name': '小花', 'type': '波斯猫', 'speed': '10m/s', 'age': 10}
print(getattr(xiaohua, 'weight', '5kg'))
# 5kg, 获取xiaohua的weight属性,此属性不存在,返回default的值
# print(getattr(xiaohua, 'weight')) # 不设置default时,属性不存在
# 会报错 AttributeError: 'Cat' object has no attribute 'weigh'
# 3.setattr(object, key, value)# 设置对象的key属性为value值
# 等同于object.key = value
setattr(xiaohua, 'weight', '5kg')
# 给xiaohua增加weight的属性
print(xiaohua.__dict__)
# {'name': '小花', 'type': '波斯猫', 'speed': '10m/s', 'age': 10, 'weight': '5kg'}
# 4.delattr(object, name) 删除对象的name字符串属性
delattr(xiaohua, 'weight')
print(xiaohua.__dict__)
# {'name': '小花', 'type': '波斯猫', 'speed': '10m/s', 'age': 10}