名称改写(Name Mangling)

在Python中,如果你在类中定义一个属性或方法时以双下划线开头(例如__attribute),Python会自动对其进行名称改写。名称改写实际上是在属性或方法名前加上类名,以避免子类意外覆盖。

举个例子,如果你有一个类MyClass,其中有一个属性__attribute,Python会将其改写为_MyClass__attribute

为什么需要名称改写

  1. 避免命名冲突: 名称改写是为了防止属性在继承时被子类意外覆盖。通过将名称改写为类特定的形式,Python确保了这些属性在类层次结构中是唯一的。

  2. 提高封装性: 通过名称改写,Python提供了一种弱私有化机制,使得类的内部实现细节不易被外界直接访问。

在调试时使用改写名称的原因

在调试或监控代码时,如果你想访问一个以双下划线开头的属性,必须使用名称改写后的名字。这是因为Python在编译时已经将名字改成了特定的格式(如_MyClass__attribute),直接使用原始名字(如__attribute)是无法找到该属性的。

如何安全使用

  1. 理解名称改写机制: 知道Python如何处理双下划线开头的属性名,可以避免在访问时出现错误。

  2. 尽量避免使用双下划线: 如果没有特别需要,尽量使用单下划线作为私有属性的标识。这可以使代码更简洁,不必担心名称改写的问题。

  3. 在调试器中使用改写的名称: 如果必须访问双下划线开头的属性,确保使用改写后的名称,以便正确访问。

通过理解名称改写,你可以更好地控制类的行为并避免常见的访问错误。

单下划线 _

  • 约定私有属性和方法:

    • 使用单下划线(如_attribute)表示属性或方法是“私有”的。这是一个约定,表示不应该从类外部访问,但实际上没有强制限制。
  • 避免与Python关键字冲突:

    • 例如,使用class_来避免与Python的关键字class冲突。
  • 临时变量:

    • 在循环或解构中,单下划线常用于表示不关心的变量。例如,for _ in range(5):表示循环计数变量不需要使用。

双下划线 __

  • 名称改写(Name Mangling):

    • 双下划线用于触发名称改写,将属性名改为_ClassName__attribute。这是一种弱私有化机制,主要用于避免属性在继承时被子类意外覆盖。
  • 适用于需要更高封装性的场景:

    • 当你希望确保属性在类外部不被直接访问,并且避免在继承中出现命名冲突时,可以使用双下划线。

选择使用的场景

  • 单下划线:

    • 适合表示约定的私有属性和方法,用户可以在外部访问,但应理解这是不推荐的。
  • 双下划线:

    • 适合需要更高封装性和避免子类冲突的场景,但使用时要了解名称改写的机制。

总结

  • 用单下划线来表示“内部使用”的属性和方法,但不是真正的私有。
  • 用双下划线在需要避免子类命名冲突时提供额外的保护。

选择使用哪种下划线取决于你的需求和代码设计的复杂性。

class Widget:def __init__(self, name):self.name = nameself.__state = "inactive"  # 私有属性,避免子类覆盖def __render(self):  # 私有方法,避免子类覆盖print(f"Rendering {self.name} widget in {self.__state} state.")def activate(self):self.__state = "active"self.__render()def deactivate(self):self.__state = "inactive"self.__render()# 子类,表示具体的按钮组件
class Button(Widget):def __init__(self, name, label):super().__init__(name)self.label = labelself.__state = "override"  # 尝试覆盖父类的私有属性(实际上是新的属性)def click(self):print(f"Button '{self.label}' clicked!")self.activate()def __render(self):  # 尝试覆盖父类的私有方法(实际上是新的方法)print(f"Rendering button {self.label} in {self._Button__state} state.")# 使用Button类
button = Button("submit_btn", "Submit")
button.click()# Button 'Submit' clicked!
# Rendering submit_btn widget in active state.

代码解释

  • Widget类中定义了一个私有属性__state和一个私有方法__render,这样可以避免子类无意中覆盖这些实现细节。
  • Button类继承自Widget,并且尝试定义相同名称的__state__render,但由于名称改写机制,父类和子类的这些名称实际上是不同的。
  • button.click()被调用时,它实际上调用了Widget类中的__render方法,而不是Button类中的__render方法,因为Button类中的__render是一个完全独立的方法。

由此可见,通过双下划线,我们能够保护Widget类中的核心实现不被子类干扰,从而确保了框架的稳定性和一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/85098.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/85098.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/85098.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

list使用及模拟

01. list介绍 list是支持常数时间内任意位置插入删除的序列容器,具备双向迭代能力。其底层为双向链表结构,各元素存于独立节点,通过指针指向前后元素。与forward_list的主要区别:后者是单链表,仅支持单向迭代,结构更简单高效。相比array、vector、deque等序列容器,list在…

NLP基础与词嵌入:让AI理解文字(superior哥深度学习系列第13期)

13_NLP基础与词嵌入:让AI理解文字 superior哥深度学习系列第十三篇 从像素到文字,从视觉到语言——让AI跨越认知的桥梁 🎯 前言:当AI学会"读懂"文字 各位小伙伴们,欢迎来到superior哥深度学习系列的第十三篇…

【时时三省】(C语言基础)关于变量的声明和定义

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 可能有些人弄不清楚定义与声明有什么区别,它们是否是一回事。有人认为声明就是定义,有人认为只有赋了值的才是定义。在C语言的学习中,关于定义与声明这两个…

Java 时间处理指南:从“踩坑”到“填坑”实战

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 场景问题:订单处理系统的时间计算 假设你正在开发一个电商订单系统,需要解决以下问题: 用户下单后,需在…

基于Java的Excel列数据提取工具实现

摘要:本文介绍了一个使用Java语言开发的Excel列数据提取工具,该工具借助Apache POI库实现对Excel文件的读取与特定列数据提取功能。通过用户输入文件路径与列名,程序可从指定Excel文件中提取相应列的数据并展示,同时详细阐述了关键…

关于人工智能未来的趋势

学而不思则罔 翻译:使用深度学习、强化学习却不用专家系统,就会产生幻觉。 思而不学则殆 翻译:只有专家系统逻辑推理,但是不用大模型更新知识,就无法发展下去了。 因此,未来智能的范式应该是: …

Java八股文——MySQL「性能调优篇」

MySQL的EXPLAIN有什么作用? 面试官您好,EXPLAIN命令是我在进行SQL性能优化时,使用最频繁、也最重要的一个工具。 它的核心作用可以一句话概括:模拟MySQL的查询优化器来执行一条SQL语句,并向我们展示出它最终决定采用…

win打印机共享处理

win打印机共享处理 软件链接 无法启动Print Spooler服务错误193:0xc1的解决方案主要涉及修复服务依赖关系、清理打印缓存及修复系统文件‌。该错误通常由系统文件损坏、注册表配置异常或依赖服务未启动导致,可通过以下步骤系统化解决。‌‌ 解决方法:替换…

C++ map代码练习 1、2、priority_queue基础概念、对象创建、数据插入、获取堆顶、出队操作、大小操作,自定义结构、代码练习 1 2

map代码练习1&#xff0c;对应力扣 两个数据的交集&#xff0c;代码见下 class Solution { public:vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {map<int, int> cnt;vector<int> ans;for(int i0; i<nums1.size(…

三天冲刺《编译原理》——笔记(一)

点关注不迷路哟。你的点赞、收藏&#xff0c;一键三连&#xff0c;是我持续更新的动力哟&#xff01;&#xff01;&#xff01; 持续关注我~~~主页&#xff0c;查看更多内容哟&#xff08;希望你能在这里有所收获&#x1f92d;&#xff09;。点关注&#xff0c;不迷路&#xf…

代理模式Proxy Pattern

模式定义 给某一个对象提供一个代理&#xff0c;并由代理对象控制对原对象的引用 对象结构型模式 模式结构 Subject&#xff1a;抽象主题角色Proxy&#xff1a;代理主题角色RealSubject&#xff1a;真实主题角色 代理类实现代码 public class Proxy implements Subject {p…

基于YOLOv11与单目测距的实战教程:从目标检测到距离估算

引言 在计算机视觉领域&#xff0c;目标检测与距离估算的结合是自动驾驶、机器人导航等场景的关键技术。本文将以YOLOv8模型为核心&#xff0c;结合单目相机的几何模型&#xff0c;实现对视频中目标的实时检测与距离估算。代码参考自单目测距原理博客&#xff0c;并通过实践验…

代码生成器使用原理以及使用方法

代码生成器使用原理以及使用方法 版本号&#xff1a;1.0 二Ο二五年二月 目录 文档介绍 1.1编写目的 1.2文档范围 1.3读者对象 系统设计 2.1设计目标 2.2设计思路 2.3代码实现原理 使用方法 3.1如何使用 3.2如何修改&#xff1f; 对原程序的bug修改及简…

STM32标准库-I2C通信

文章目录 一、I2C通信1.1 I2C1.2硬件电路1.3I2C时序基本单元1.4I2C时序 二、MPU60502.1简介2.2MPU6050参数2.3硬件电路2.4MPU6050框图 三、I2C外设(硬件)3.1简介3.2I2C框图3.3I2C基本结构3.4主机发送3.5主机接收3.6软件/硬件波形对比1. 时序精度2. 信号稳定性3. 速率与效率4. 波…

使用 Azure LLM Functions 与 Elasticsearch 构建更智能的查询体验

作者&#xff1a;来自 Elastic Jonathan Simon 及 James Williams 试用这个示例房地产搜索应用&#xff0c;它结合了 Azure Gen AI LLM Functions 与 Elasticsearch&#xff0c;提供灵活的混合搜索结果。在 GitHub Codespaces 中查看逐步配置和运行该示例应用的方法。 更多阅读…

模糊查询 的深度技术解析

以下是 模糊查询 的深度技术解析&#xff0c;涵盖核心语法、通配符策略、性能优化及实战陷阱&#xff1a; &#x1f50d; 一、核心运算符&#xff1a;LIKE SELECT * FROM 表名 WHERE 列名 LIKE 模式字符串;&#x1f3af; 二、通配符详解 通配符作用示例匹配案例%任意长度字符…

[论文阅读] (39)EuroSP25 CTINEXUS:基于大模型的威胁情报知识图谱自动构建

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0c;非常欢迎大家给我留言评论&#xff0c;学术路上期…

强化学习三大分类

核心目标&#xff1a; 教会一个智能体&#xff08;比如机器人、游戏AI、推荐系统&#xff09;通过试错和奖励&#xff0c;学会在某个环境中完成特定任务的最佳策略。 核心角色&#xff1a; 智能体 (Agent)&#xff1a; 学习者&#xff0c;比如玩游戏的小人、控制温度的空调系…

城市排水生命线安全运行监测项目

近年来&#xff0c;城市内涝、污水溢流等问题频发&#xff0c;让排水管网这一"城市生命线"的安全运行备受关注。如何让地下的"毛细血管"更智能、更可靠&#xff1f;本文将带您深入解析城市排水生命线安全运行监测项目的建设逻辑与技术内核&#xff0c;看科…

LeetCode - 34. 在排序数组中查找元素的第一个和最后一个位置

题目 34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 思路 查找左边界 初始化 left 0, right nums.size() - 1 当 left < right 时循环&#xff1a; 计算中点 mid left (right - left) / 2 如果 nums[mid] < target…