Python的反射机制 -- 动态类型语言的关键

动态类型语言:在代码运行期间才去做数据类型检查的语言
与之相近的是一个动态语言:程序在运行时可以改变其结构。新的函数可以被引进,已有的函数可以被删除等在结构上的变化。比如下面Python代码,函数就被在运行时可以被改变

class Person:
	def __init__(self):
		self.name = "王二狗"

	def run(self):
		print(f"我的名字是{self.name}, 我在跑步")

	def sleep(self):
		print(f"我叫{self.name}, 我在睡觉")

p = Person()
p.run()

Person.run = Person.sleep
p.run()

为什么要有反射机制:能够让程序动态的获取对象属性或方法,在学习用Python写Python解释器的时候,反射机制很有用(Python的底层也在使用反射机制)

# 我们定义一个函数,来获取对象中的age属性
def f1(obj):   
	print(obj.age)  
  
f1(18)  
# 代码会报错,"int object has no attribute 'age'"
# 所以我们需要进行判断
# 判断一个属性在不在这个对象的__dict__中
def f1(obj):
	if "age" in obj.__dict__:
		return None
	print(obj.age)

f1(18)
# 代码也会报错,'int' object has no attribute '__dict__'. Did you mean: '__dir__'
# 思路是对的,先进行一个判断,在去拿值,但是不是所有对象都有__dict__属性

# Python 提供了一个函数dir(),可以查看一个对象中的属性
def f1(obj):  
	if "age" not in dir(obj):  
		return None  
	print(obj.age)  
  
f1(18)

# 当前我们只查看一个对象的一个属性,要看多个属性呢,写很多个if分支来判断吗
# 可以给函数传参,让属性进行一个动态的变化
def f1(obj, par_attr):  
	if par_attr not in dir(obj):  
		return None  
	print(obj.par_attr)  
  
f1(18, attr)
# 当我们执行代码时,报错了 'int' object has no attribute 'par_attr'
# 这是因为obj.par_attr编译成字节码,我们用dis库反汇编为LOAD_attr,这个指令把par_attr当成属性,进行压栈。并且这个写法还存在一个问题,attr为str类型,字符串,obj."age"在Python是不被允许的,报语法错误

# 这个时候就需要用到Python的4个内置函数   --  通过字符串的的方式来操作属性
# hasattr(obj, 属性)                     # 判断对象是否有某个属性  返回值为布尔值(Boolean)
# getattr(obj, 属性, 没有属性时的值)      # 获取对象的某个属性  
# setattr(obj, 属性, value)              # 更改对象的某个属性的值  
# delattr(obj, 属性)                     # 删除对象的某个属性
def f1(obj, par_attr):
	if hasattr(obj, par_attr):
		print(getattr(obj, par_attr))
	return f"没有该属性--{par_attr}"

# 还可以这么写
def f1(obj, par_attr):
	print(getattr(obj, par_attr, f"没有该属性--{par_attr}"))

# 看一个案例
class Person:
	def run(self):
		print("我正在跑")

	def sleep(self):
		print("我正在睡觉")

	def user_operate(self):
		opt = input("请输入您的操作:")
		getattr(self, opt, self.warning)()

	def warning(self):
		print("没有该操作")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值