对比 hasattr(),getattr() 和 setattr() 的用法。
上周晚上加班写爬虫,数据源那边 API 文档写得跟谜语一样,字段说有就有,说没就没。为了不让程序天天因为一个缺失字段崩掉,我就翻出来了 Python 里这仨老熟人:hasattr()、getattr() 和 setattr()。用着用着发现它们仨关系还挺有意思,今天就跟你聊聊。
先说 hasattr(),问就是“你有吗?”
这个函数就是用来判断对象有没有某个属性的。 返回值是布尔型,有就 True,没有就 False。 用法特别直白:
classUser:
def__init__(self, name):
self.name = name
u = User("小李")
print(hasattr(u, "name")) # True
print(hasattr(u, "age")) # False
我自己经常是在调用 getattr() 之前先来个 hasattr(),不然有些对象真是“裸奔”的,一取属性就给你报错。
然后是 getattr(),取值神器
getattr() 是获取对象属性值的,语法是:
getattr(obj, name[, default])
这里 default 是可选的,给了就算属性不存在也不会报错,直接返回这个默认值。
classUser:
def__init__(self, name):
self.name = name
u = User("小李")
print(getattr(u, "name")) # 小李
print(getattr(u, "age", 18)) # 18
有一次我直接用 getattr() 做动态调用方法,感觉比 if-else 判断方法名优雅多了。
classAction:
defrun(self):
print("running")
defjump(self):
print("jumping")
a = Action()
for action in ["run", "jump"]:
func = getattr(a, action, None)
if callable(func):
func()
这样代码可扩展性就很舒服。
最后是 setattr(),说白了就是“加个属性”
setattr() 的作用是动态给对象添加或修改属性,语法:
setattr(obj, name, value)
classUser:
def__init__(self, name):
self.name = name
u = User("小李")
setattr(u, "age", 20)
print(u.age) # 20
# 改一下已有属性
setattr(u, "name", "小王")
print(u.name) # 小王
我用它干过一个挺有意思的事,就是批量把配置文件里的键值对塞进对象里,省得一个个写。
config = {"host": "localhost", "port": 3306}
classDB:
pass
db = DB()
for k, v in config.items():
setattr(db, k, v)
print(db.host, db.port) # localhost 3306
三者的配合
它们配合起来其实就一句话:先 hasattr() 看看有没有 → 用 getattr() 取 → 用 setattr() 改或加。
比如处理接口返回的数据时,我就会:
if hasattr(u, "score"):
val = getattr(u, "score")
else:
setattr(u, "score", 0)
这样不管字段来没来,程序都能稳住。
我自己觉得,hasattr() 就像前台保安,getattr() 是你去前台要东西,setattr() 是你给前台送快递。 用熟了,很多反射、动态赋值的需求都能一把梭解决。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领