😵 反射?听起来好高端!
讲真的,第一次听到"反射"这个词,我的第一反应是"这跟照镜子有什么关系?"😅 结果发现,它还真跟"照镜子"有点像------反射让Python代码可以"看见"自己,甚至还能动态修改自己的属性和方法!
这听上去是不是有点魔法的感觉?放心,今天花姐就来带你从零搞懂Python的反射机制,保证你看完能用它装X------呃,不,是提升Python开发技能!😎
🎯 什么是Python的反射?
简单来说,反射就是让程序在运行时动态地获取、修改、调用对象的属性或方法。
想象一下,你有一个同事(假设叫小李),你可以:
- 问他的名字(获取属性)
- 让他倒杯咖啡(调用方法)
- 给他取个外号(修改属性)
- 偷偷让他干活(动态调用方法)😂
Python里的反射就能做到类似的事情,比如:
getattr()
获取对象的属性或方法setattr()
修改或添加属性hasattr()
检查对象是否有某个属性delattr()
删除属性
🧐 为什么要用反射?
正常写代码,我们直接 obj.method()
这样调用方法不就行了吗?为什么要折腾反射?
🤔 反射的用武之地主要在 以下几种场景:
- 动态加载类和方法(比如插件系统、框架内部机制)
- 提升灵活性(让代码更具通用性,比如配置化调用)
- 处理未知对象(比如ORM框架,反射数据库字段)
- 减少硬编码 (通过字符串调用方法,避免
if-elif
大量判断)
如果这些听起来有点抽象,别担心,我们马上用代码来解释!💡
🛠 反射的基本用法
1️⃣ getattr()
- 获取属性或方法
python
class Person:
def __init__(self, name):
self.name = name
def say_hello(self):
return f"Hi, I am {self.name}!"
p = Person("花姐")
# 通过反射获取属性
print(getattr(p, "name")) # 输出:花姐
# 通过反射获取方法,并调用它
method = getattr(p, "say_hello")
print(method()) # 输出:Hi, I am 花姐!
💡 小细节: getattr()
在找不到属性时会抛出 AttributeError
,可以传入一个默认值来避免报错:
python
print(getattr(p, "age", "未知")) # 输出:未知
2️⃣ setattr()
- 修改或新增属性
python
setattr(p, "age", 18) # 给对象动态添加属性
print(p.age) # 输出:18
setattr(p, "name", "Python大佬") # 修改已有属性
print(p.name) # 输出:Python大佬
这就相当于你给小李取了个外号,并且他还接受了!😆
3️⃣ hasattr()
- 检查属性是否存在
python
print(hasattr(p, "name")) # 输出:True
print(hasattr(p, "height")) # 输出:False
就像八卦小王打听同事有没有女朋友一样,这个方法专门用来检查"有没有"!😏
4️⃣ delattr()
- 删除属性
python
delattr(p, "age") # 删除属性
print(hasattr(p, "age")) # 输出:False
用完就删,干净利落!但注意:删除后再访问会报错哦。
🔥 高阶用法:用反射调用未知方法
有时候,我们的代码需要在运行时决定调用哪个方法,比如用户输入了一个方法名,我们要动态调用它:
python
class Robot:
def walk(self):
print("机器人在走路!")
def talk(self):
print("机器人在说话!")
r = Robot()
# 假设方法名是动态传入的
method_name = input("输入方法名(walk/talk):")
if hasattr(r, method_name):
method = getattr(r, method_name)
method() # 动态调用方法
else:
print("方法不存在!")
💡 小技巧: 这样可以避免 if method_name == "walk": r.walk()
这种硬编码方式,让代码更灵活!
🚀 反射 + __dict__
,玩转动态对象
__dict__
是 Python 对象的"内存字典",可以用它直接查看和修改对象的属性。
python
class Config:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
c = Config(debug=True, db="mysql")
print(c.__dict__) # 输出:{'debug': True, 'db': 'mysql'}
妙用场景:
- 配置对象的快速创建
- 序列化和反序列化
🎬 结语
到这里,你已经掌握了Python的反射机制,并能灵活运用 getattr()
、setattr()
、hasattr()
和 delattr()
了!🎉
这玩意儿就像黑客工具,一不小心就能写出各种炫技代码(当然,也要注意别滥用,否则代码会变得难以维护!)。
如果你觉得这篇文章有帮助,顺手 点赞 + 在看 就是对花姐最大的支持!❤️