python __getattr__动态属性访问

Python getattr函数详解:动态属性访问的正确用法与避坑指南 在Python中,getattr()是实现动态属性访问的核心内置函数,它基于对象的属性协议(__getattribute__/__getattr__)提供显式、安全、可控的字段读取能力。相比硬编码obj.attr或危险的eval(),getattr()通过字符串键名实现运行时属性查找,天然规避代码注入风险,并支持优雅降级(default参数)。其技术价值在于 bridging 静态类型开发与配置驱动、数据驱动场景——如爬虫解析HTML字段、YAML配置加载、API响应按需序列化等。广泛应用于python零基 阅读详情

在普通的字典中访问属性中,不能使用.运算符链式调用下去,现在实现__getattr__ 协议,构建一个类,实现简单版本的json数据链式访问,来说明动态属性的访问。
先来看原始的方式:

# -*- coding: utf-8 -*-
feed = {
    "Schedule":
        {
            "conferences": [{"serial": 115}],
            "events": [
                {"serial": 34505,
                 "name": "Why Schools Don´t Use Open Source to Teach Programming",
                 "event_type": "40-minute conference session",
                 "time_start": "2014-07-23 11:30:00",
                 "time_stop": "2014-07-23 12:10:00",
                 "venue_serial": 1462,
                 "description": "Aside from the fact that high school programming...",
                 "website_url": "http://oscon.com/oscon2014/public/schedule/detail/34505",
                 "speakers": [157509],
                 "categories": ["Education"]}
            ],
            "speakers": [
                {"serial": 157509,
                 "name": "Robert Lefkowitz",
                 "photo": None,
                 "url": "http://sharewave.com/",
                 "position": "CTO",
                 "affiliation": "Sharewave",
                 "twitter": "sharewaveteam",
                 "bio": "Robert ´r0ml´ Lefkowitz is the CTO at Sharewave, a startup..."}
            ],
            "venues": [
                {"serial": 1462,
                 "name": "F151",
                 "category": "Conference Venues"}
            ]
        }
}

if __name__ == '__main__':
    print(feed['Schedule'].keys())
    # dict_keys(['conferences', 'events', 'speakers', 'venues'])
    print(feed['Schedule']['speakers'][-1]['name'])
    # Robert Lefkowitz

示例很简单,但feed['Schedule']['speakers'][-1]['name']这种句法很冗长。在 JavaScript 中,可以使用 feed.Schedule.speakers[-1].name 获取那个值。在 Python 中,可以实现一个近似字典的类(网上有大量实现),达到同样的效果。我自己实现了 FrozenJSON
类,比大多数实现都简单,因为只支持读取,即只能访问数据。不过,这个类能递归,自动处理嵌套的映射和列表。

# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
from collections import abc

feed = {
    "Schedule":
        {
            "conferences": [{"serial": 115}],
            "events": [
                {"serial": 34505,
                 "name": "Why Schools Don´t Use Open Source to Teach Programming",
                 "event_type": "40-minute conference session",
                 "time_start": "2014-07-23 11:30:00",
                 "time_stop": "2014-07-23 12:10:00",
                 "venue_serial": 1462,
                 "description": "Aside from the fact that high school programming...",
                 "website_url": "http://oscon.com/oscon2014/public/schedule/detail/34505",
                 "speakers": [157509],
                 "categories": ["Education"]}
            ],
            "speakers": [
                {"serial": 157509,
                 "name": "Robert Lefkowitz",
                 "photo": None,
                 "url": "http://sharewave.com/",
                 "position": "CTO",
                 "affiliation": "Sharewave",
                 "twitter": "sharewaveteam",
                 "bio": "Robert ´r0ml´ Lefkowitz is the CTO at Sharewave, a startup..."}
            ],
            "venues": [
                {"serial": 1462,
                 "name": "F151",
                 "category": "Conference Venues"}
            ]
        }
}


class FrozenJSON:
    """一个只读接口,使用属性表示法访问JSON类对象"""

    def __init__(self, mapping):
        # 使用 mapping 参数构建一个字典。这么做有两个目的:(1) 确保传入的是字典(或者是
        # 能转换成字典的对象);(2) 安全起见,创建一个副本。
        self.__data = dict(mapping)

    def __getattr__(self, name):  # 仅当没有指定名称(name)的属性时才调用 __getattr__ 方法
        if hasattr(self.__data, name):
            # 如果 name 是实例属性 __data 的属性,返回那个属性。调用 keys 等方法就是通过这种
            # 方式处理的。
            return getattr(self.__data, name)
        else:
            # 否则,从 self.__data 中获取 name 键对应的元素,返回调用 FrozenJSON.build() 方法
            # 得到的结果
            return FrozenJSON.build(self.__data[name])

    @classmethod
    def build(cls, obj):  # 这是一个备选构造方法,@classmethod 装饰器经常这么用
        if isinstance(obj, abc.Mapping):  # 如果 obj 是映射,那就构建一个 FrozenJSON 对象
            return cls(obj)
        elif isinstance(obj, abc.MutableSequence):  # 如果是 MutableSequence 对象,必然是列表,
            # 因此,我们把 obj 中的每个元素递归地传给 .build() 方法,构建一个列表
            return [cls.build(item) for item in obj]
        else:   # 如果既不是字典也不是列表,那么原封不动地返回元素
            return obj


if __name__ == '__main__':
    # print(feed['Schedule'].keys())
    # # dict_keys(['conferences', 'events', 'speakers', 'venues'])
    # print(feed['Schedule']['speakers'][-1]['name'])
    # # Robert Lefkowitz

    new_feed = FrozenJSON(feed)
    print(new_feed.Schedule.keys())
    print(len(new_feed.Schedule.speakers))
    # 1
    print(new_feed.Schedule.speakers[-1].name)
    # Robert Lefkowitz
    print(new_feed.name)
    #     return FrozenJSON.build(self.__data[name])
    # KeyError: 'name'


FrozenJSON 类的关键是 __getattr__ 方法。我们要记住重要的一点,仅当无法使用常规的方式获取属性(即在实例、类或超类中找不到指定的属性),解释器才会调用特殊的 __getattr__ 方法。

print(new_feed.name)一行揭露了这个实现的一个小问题:理论上,尝试读取不存在的属性应该抛出 AttributeError 异常,但这里只是说了__getattr__使用,没有去做复杂的实现。

Python getattr()原理与工程实践:动态属性访问核心指南 getattr() 是 Python 反射机制的基础接口,本质是封装了完整的属性查找链(MRO + 描述符协议 + __getattr__兜底),区别于直接操作 __dict__ 的粗粒度访问。它支撑着动态字段读取、方法绑定、配置驱动、插件发现等关键能力,在 Django、Pydantic 等主流框架中高频使用。其三参数设计(对象、属性名、默认值)天然契合 EAFP 哲学,使代码兼具健壮性与可读性;配合 operator.attrgetter 可高效处理嵌套路径。掌握 getattr(),即掌握 Pytho 阅读详情

相关推荐

Python中的动态属性管理:使用__getattr__和__setattr__实现灵活的数据访问

在Python中,`__getattr__`和`__setattr__`是两种强大的魔法方法,用于动态管理属性访问。通过这些方法,开发者可以实现对属性的灵活访问和赋值,创建更具弹性的类设计,尤其适合处理具有不确定属性的数据结构。本文将详细介绍如何使用`__getattr__`和`__setattr__`实现动态属性访问和赋值,并结合丰富的代码示例展示如何利用这些方法优化类的设计。我们还将探索`__delattr__`的作用,展示如何在Python中构建具有动态属性的灵活类,为复杂数据访问需求提供解决方案。

一个被知识诅咒的人 1911

python访问属性的格式_Python 中几种属性访问的区别

图 | 《借东西的小人阿莉埃蒂》剧照起步python的提供一系列和属性访问有关的特殊方法:__get__, __getattr__, __getattribute__, __getitem__。本文阐述它们的区别和用法。属性的访问机制一般情况下,属性访问的默认行为是从对象的字典中获取,并当获取不到时会沿着一定的查找链进行查找。例如 a.x 的查找链就是,从 a.__dict__['x'] ,然后...

weixin_31837543的博客 237

Python中的动态属性:用__getattr__和__setattr__实现灵活的数据访问

在面向对象编程中,属性的灵活性和可扩展性至关重要。Python 提供了 `__getattr__` 和 `__setattr__` 魔法方法,使开发者能够动态地控制属性的访问和赋值,从而打造更加灵活和强大的类设计。本文深入探讨了这两个方法的工作原理,展示了如何通过它们实现动态属性访问,提升类的可扩展性和可维护性。我们将通过丰富的代码示例和详细的中文注释,演示如何在实际项目中应用这些技术,包括动态属性的创建、访问控制、数据验证以及与其他设计模式的结合应用。此外,文章还讨论了使用动态属性时需要注意的性能和安全性

一个被知识诅咒的人 1393

【Python】深入了解Python中的属性访问控制:通过__getattr__与__setattr__实现动态属性管理

在Python中,类的属性访问控制是通过魔术方法(magic methods)实现的,其中`__getattr__`和`__setattr__`是两个至关重要的魔术方法。本文将深入探讨这两个方法的原理和用法,展示它们如何支持动态属性的管理、访问控制以及数据封装等高级特性。通过丰富的代码示例和解释,帮助读者理解如何灵活地通过这两个方法定制类的属性行为。 本文将通过以下几个方面来展开讨论:如何使用`__getattr__`获取不存在的属性,如何通过`__setattr__`控制属性的设置,如何通过这两个方法实

一个被知识诅咒的人 1188

在ros里给机械臂加上夹爪和底盘后,控制真实机械臂

使用ur3_bringup 可以连接真实机械臂 使用官方的ur3_moveit_planning_execution.launch 可以对机械臂 moveit规划。 但是只有机械臂,没有夹爪。 官方如图: 我把原来的ur3_moveit_config 复制出来,修改 然后把ur3.xacro 等模型文件复制出来修改,修改完之后,有了夹爪,有了底盘。 规划组什么的使用moveit setup assistant 配置过了。 在rviz中可以笛卡尔空间规划了。 ...

超级菜 2716

创新实训项目博客:基于LoRA的医疗大模型高效微调实战

预训练大语言模型(LLMs)虽然具备了广泛的知识和一定的通用能力,但在特定领域(如医疗)或特定任务(如遵循特定指令格式进行思考链推理)上,其表现往往不尽如人意。微调(Fine-tuning)能够使模型学习到特定领域的数据分布和任务模式,从而在目标任务上获得更好的性能,使其更贴合实际应用需求。使用Unsloth框架加载并以4-bit量化模型。基于数据集,构建了包含明确思考链引导的训练Prompt。配置了LoRA参数,并使用SFTTrainer在单张T4 GPU上对模型进行了高效微调。

m0_73556916的博客 1290

Python的__getattr__魔术方法在动态属性访问与代理模式中的应用

_getattr__是实现惰性加载的理想工具。通过重写__getattr__,当访问obj.database_config时,方法会检查该配置是否已加载,若未加载则从文件读取并缓存结果。其中,__getattr__魔术方法就像一扇隐藏的大门,允许我们在属性访问时插入自定义逻辑。比如要为某个对象创建保护代理,可以在代理类中定义__getattr__,将所有属性访问重定向到被代理对象,同时加入权限检查逻辑。通过以上示例可以看出,__getattr__这个看似简单的方法,实则是Python动态编程的瑞士军刀。

ivmkvz_222的博客 235

gdb对dwarf调试信息的解析和使用

gdb的对dwarf的调试信息的解析到使用的过程分析

JS072110的专栏 9568

Python中的getattr()函数详解

Python中的getattr()函数详解 最近看Dive into python第四章自省中提到getattr()函数,作为一个内建函数平时自己没怎么用过所以也不太理解这个函数的一些用法 看了下函数本身的doc getattr(object, name[, default]) -> value Get a named attribute from an object; g

jfkidear的专栏 2252

Surface Pro 4/5/6/7保姆级黑苹果安装:从Windows分区到OC引导配置全流程(含EFI文件替换避坑)

本文详细介绍了在Surface Pro 4/5/6/7上安装黑苹果的全流程,包括Windows分区、OC引导配置和EFI文件替换等关键步骤。通过实战经验分享,帮助用户避开常见陷阱,实现Windows与macOS双系统完美共存,特别适合对黑苹果安装感兴趣的Surface Pro用户。

weixin_30300225的博客 1373

ACM论文LaTeX模板解析(三)| 文章顶部信息(Top matter))Part 1

文章顶部信息(Top matter))Part 1,文章类型、作者信息等

FreshManInC的博客 4853

python getattr_python __getattr__

这是python里的一个内建函数,当调用的属性或者方法不存在时,该方法会被调用调用不存在的属性class Student(object):def __getattr__(self, attr):if attr in ('name', 'age', 'score'):print attrelse:raise AttributeError('Unkonw attribute : %s' % attr)...

weixin_39704727的博客 231

华为OD机试 - 去除多余空格(Python/JS/C/C++ 2024 E卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。条件约束:输入为两行字符串:第一行:待去除多余空格的文本,用例保证如果有单引号,则单引号成对出现,且单引号可能有多对。 第二

学Java,找哪吒 1216

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

Python内置函数getattr()用于动态获取对象属性,支持通过字符串指定属性名,比点运算符更灵活。其语法为getattr(object, name[, default]),当属性不存在时可返回默认值。文章通过Person类示例展示了getattr()在动态属性访问中的优势,并对比了点运算符的局限性。同时深入解析了getattr()底层调用__getattribute__()的机制,以及__getattr__()方法在属性不存在时的处理逻辑。

保持终身学习的能力,温故而知新 1707

21天教你学会PCIe专栏(17)--多功能设备

1.1 定义多功能PCIe设备:多功能PCIe设备是指在一个物理设备中集成了多种功能的设备。这些功能可以通过不同的PCIe功能(Function)来实现,每个功能可以独立配置和管理。1.2 优点资源利用率:通过集成多种功能,减少物理设备的数量,提高资源利用率。成本效益:减少硬件成本和功耗,提高系统的经济性。灵活性:用户可以根据需要启用或禁用不同的功能,提高系统的灵活性。可扩展性:通过增加新的功能,扩展设备的功能,提高系统的可扩展性。1.3 应用场景网络设备。

xiaoheshang_123的博客 531

LPDDR5 学习笔记08:电气参数设计要求

本文详细阐述了LPDDR5内存接口的关键电气规范和时序要求。主要内容包括:1)绝对最大额定值限制及长期工作可靠性说明;2)差分时钟信号(CK/WCK)的输入电压、转换速率和交叉点电压规范;3)单端时钟信号的定义和测量方法;4)时钟周期、抖动(周期抖动、相邻周期抖动)和累积误差的精确计算方法;5)片选信号在同步/异步模式下的接收器规范;6)命令地址信号和数据信号的接收器掩模定义及脉冲宽度要求。所有参数均严格定义了测量条件和合规标准,为LPDDR5接口设计提供了完整的电气规范参考。

一只豌豆象的博客 1181

如何用Python的__getattr__魔法方法实现动态属性访问

例如构建一个万能占位对象,当访问任意属性时都返回None,只需定义def __getattr__(self, name): return None。其中,__getattr__魔法方法允许开发者实现动态属性访问,为对象赋予"智能响应"的能力。当访问不存在的属性时,Python会调用这个方法,这为创建灵活的数据结构、实现代理模式或构建DSL等领域打开了新的大门。通过合理运用__getattr__,开发者可以创造出高度灵活的对象模型。当需要动态扩展对象功能时,__getattr__可将请求转发到其他对象。

ggfbvv_392的博客 37

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

魔法方法《七》__getattr__

__getattr__ 当访问object不存在的属性时会调用__getattr__方法 示例一 class House(): def __init__(self, name, age): self.name = name self.age = age def __getattr__(self, item): re...

风华浪浪的博客 338

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

python 如何用__getattr__和__getattribute__实现动态属性?

在 Python 中,和是两个特殊的魔法方法,它们可以用来实现动态属性。

qq_62784677的博客 494

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

python getattr用法_对比Python中__getattr__和 __getattribute__获取属性的用法

相信大家觉得大多数时候我们并不太需要关注getattribute和getattr的一些细节(至少我自己吧:)),一般情况下消费我们自定义的类的时候,我们对类的结构都了解,不会刻意偏离,造成一些属性访问的错误。不过作为一个有好奇心有追求有气质的python宝宝,怎么可能不稍稍研究一下呢。好吧,其实是在github上读到一个开源项目sinaweibopy的源码才看的,代码挺有意思,正好当作一个实用的例...

weixin_39657575的博客 293
上一篇: python 函数内省
下一篇: python3 venv 管理多个python解释器
MZP_man
博客等级 码龄8年 188粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值