在Python编程中,我们习惯使用(对象.属性)的方式 访问数据或者方法。但是在某些场景下,这种硬编码的写法会显得捉襟见肘。例如要访问的属性名是用户输入的内容;或者属性存在配置文件里;运行时才知道要调用哪个属性。这时候,getattr()这个内置函数就能派上大用场。首先是getattr动态访问属性,平时我们在访问对象属性时,用的是点标记法:这种写法的前提是在我们写代码时,就要知道属性名是什么。而getattr()允许我们用字符串来动态指定属性名:最重要体现在动态性上,例如我们定义一个变量 存储属性名:attr = "name"# 这样写会报错!Python 会去找 p 里的 attr 属性,而不是 namep.attr# 这样写才对getattr(p, attr)
为什么动态访问这么重要呢?我们来通过例子来看看,我们定义一个Person类:class Person: def __init__(self): self.name = "Alice" self.age = 30person = Person()
现在需要批量获取name和age两个属性值,如果不用getattr,就得写一堆if-elif分支:fields = ["name", "age"]for field in fields: if field == "name": print(person.name) elif field == "age": print(person.age)
fields = ["name", "age"]for field in fields: print(getattr(person, field))
不管后面加多少属性,循环逻辑都不用改变,这就是动态编程的简洁性。getattr还有一个超实用的功能,属性不存在时,返回默认值。如果直接用点标记法来访问不存在的属性,Python就会抛出AttributeError异常:# 报错:'Person' object has no attribute 'height'person.height
用getattr时,你可以传入第三个参数作为默认值:# 不会报错,返回默认值 170getattr(person, "height", 170)
这个特性在处理不确定的属性时非常的好用,能让程序更健壮。在Python中方法也是一种属性,所以getattr同样可以动态调用方法。举个计算器的例子:class Calculator: def add(self, x, y): return x + y def multiply(self, x, y): return x * ycalc = Calculator()
# 获取 add 方法对象method = getattr(calc, "add")# 调用方法print(method(2, 3)) # 输出 5
这个特性在做插件化开发,命令分发时特别有用。比如根据用户输入的命令字符串,动态调用对应的处理函数。既然它这么好为什么通常情况 用的并不频繁呢?首先它和点标记法在实用性能上基本没差别,而且点方式更简洁。总之,getattr在需要它的时候再去用,千万不要为了炫技让代码变得晦涩难懂。