Python:getattr()函数和__getattribute__()魔术方法

探讨了Python中getattr()函数的用法,如何动态获取对象属性,以及与点运算符的异同,涉及魔术方法如__getattribute__()和__getattr__()的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相关阅读

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'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日晨难再

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值