相关阅读
Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html
getattr()是一个python内置的函数,用于获得一个对象的某个属性(仅能作为右值),一般情况下,可以通过点运算符.完成相同的功能,但是getattr()拥有一个点运算符无法实现的功能,就是允许使用字符串(甚至字符串内容可以不是一个标识符,因为可以使用setattr()设置属性)来表示属性名,从而可以在运行时动态地选择要获取的属性,这对于编写通用的代码或者处理动态数据结构很有用。
下面是getattr()函数的函数头。
getattr(object, name[, default])
其中参数object是要获取属性的对象;参数name是一个字符串,表示要获取属性的名称,它可以接受变量作为实参;default是一个可选项,表示如果指定的属性不存在,返回的默认值。
下面是一个简单的例子,展示了getattr()函数的便捷之处。
# 例1
# 定义了一个Person类,包含name、age、gender三个属性
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
# 定义了一个函数,它获取对象的一个属性
def print_person_property(person, property_name):
try:
value = getattr(person, property_name)
print(f"{property_name}: {value}")
except AttributeError:
print(f"Error: {property_name} is not a valid property.")
# 创建一个 Person 对象
person = Person("Alice", 30, "Female")
# 用户输入要打印的属性名
input_property = input("Enter property name (name, age, gender): ")
# 打印属性值或错误信息
print_person_property(person, input_property)
# 输出
Enter property name (name, age, gender): name
name: Alice
如果直接使用点运算符,则会报错,如下例所示。
# 例2
# 定义了一个Person类,包含name、age、gender三个属性
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
# 创建一个 Person 对象
person = Person("Alice", 30, "Female")
# 用户输入要打印的属性名
input_property = input("Enter property name (name, age, gender): ")
# 打印属性值或错误信息
print_person_property(person.input_property)
# 输出
Enter property name (name, age, gender): name
Traceback (most recent call last):
File "c:\Users\12078\Desktop\python\test.py", line 22, in <module>
print_person_property(person.input_property)
AttributeError: 'Person' object has no attribute 'input_property'
深入了解getattr()函数,可以发现其是通过调用类的魔术方法__getattribute__()来访问属性的(对于点运算符访问属性,也是通过这种方式),但是不建议直接使用__getattribute__()来访问属性。
# 例3
# 定义了一个测试类,拥有三个属性
class Test:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
test_class = Test()
# 直接使用 __getattribute__ 方法访问属性
print(test_class.__getattribute__('a'))
print(test_class.__getattribute__('b'))
print(test_class.__getattribute__('c'))
# 输出
1
2
3
当访问一个不存在的属性时,产生的AttributeError异常也是由__getattribute__()引发的,下面的例子可以说明这一点。
# 例4
# 定义了一个测试类,拥有三个属性
class test():
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def __getattribute__(self,item): # 重写了__getattribute__,导致其能访问到本不存在的属性
return "Test"
test_class=test()
print(getattr(test_class, "d", "Default")) # 访问一个不存在的属性d
print(test_class.d)
# 输出
Test
Test
在使用getattr()函数(或点运算符)在__getattribute__()中引发了AttributeError异常后,Python解释器会首先尝试调用__getattr__(),并使用其返回值替代。接着,如果不存在__getattr__()(它是一个对象默认没有的),并且访问属性的方式不是使用带有默认值的getattr()函数,则会出现AttributeError异常并结束,如果是使用带有默认值的getattr()函数访问属性,则会使用默认值替代,下面是两个例子。
# 例5
# 定义了一个测试类,拥有三个属性
class test():
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
def __getattr__(self, item): # 为了在访问一个不存在的属性时产生异常,我们只重写了__getattr__()方法
return "Default2"
test_class=test()
print(getattr(test_class, "d", "Default1")) # 优先使用__getattr__()方法的返回值替代而不是"Default1"
print(test_class.d)
# 输出
Default2
Default2
# 例6
# 定义了一个测试类,拥有三个属性
class test():
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
test_class=test()
print(getattr(test_class, "d", "Default1")) # 当不存在__getattr__()方法时,使用"Default1"替换
print(test_class.d) # 当使用点运算符访问不存在的属性且不存在__getattr__()方法时,会产生异常并结束
# 输出
Default1
Traceback (most recent call last):
File "c:\Users\12078\Desktop\test1\test.py", line 16, in <module>
print(test_class.d)
AttributeError: 'test' object has no attribute 'd'