Python技术迷

对比 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 全部免费领