当前位置: 首页 > article >正文

Python自学 - 封装与私有化

1 Python自学 - 封装与私有化

1.1 封装的概念

  封装是指将数据和方法封装在一起,并且需要通过类的实例来访问,这样就可以确保合适的方法来处理合适的数据,并可以做到只给外界看到想给外界看到的接口,减少数据或方法被滥用的风险。
  读者如果还记得类的定义(属性、方法)章节的内容,一定会想起函数式编程里面,可以搞出“人吃草”、“牛吃粮食”的荒唐事来,“人会不会吃草”,完全仰仗编程人员的水平。而使用类封装过后,人就是人,牛就是牛, 人就干人事,牛就干牛事,少了一些荒唐(不能保证绝对没有!毕竟,人类啥事都做得出来!)

示例代码:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def display(self):
        print(f"Name: {self.name}, Age: {self.age}")


# 创建 Person 类的实例
person = Person("Alice", 30)
person.display()

上述示例中的Person类封装了nameagedisplay方法,这些属性和方法只适用于Person类创建的对象,绝对不会和Cow类混用。

1.2 私有化

Python不像JavaC++C#等语言,Python没有提供了关键字publicprivate, protect用来表示属性或方法的适用范围。
  但Python提供了一些折中的方法来控制属性或方法的范围。

1.2.1 方法1:使用单下划线_前缀

  使用单下划线 _ 作为属性或方法的前缀,仅是一种约定,表示该成员应该被视为受保护的,即不应该被外部直接访问,但实际上仍然可以被访问

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    def display(self):
        print(f"Name: {self._name}, Age: {self._age}")


# 创建 Person 类的实例
person = Person("Bob", 25)
person.display()
print(person._name)  # 可以访问,但不建议

1.2.2 方法2:使用双下划线__前缀

  使用双下划线 __ 作为属性或方法的前缀,会将其名称进行名称改编(name mangling),使得从外部难以直接访问该成员,实际上如果读者知道改名规则后,仍然可以直接使用改名后的名称访问。
  实际上只是把属性或方法稍稍进行了掩人耳目,并没有严格进行私有化限定。
示例:

class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def display(self):
        print(f"Name: {self.__name}, Age: {self.__age}")


# 创建 Person 类的实例
person = Person("Charlie", 40)
person.display()
# 以下会报错,因为 __name 已经被名称改编
# print(person.__name)

# 可以通过名称改编后的名称访问,但不建议
print(person._Person__name)

改名的规则是在原名前再加_类名做为前缀。

  • 封装和私有化的优点
    • 信息隐藏:将内部实现细节隐藏,只暴露必要的接口,使类的使用更加简单和安全。
    • 防止意外修改:限制外部对重要数据和方法的直接访问,避免意外修改导致的错误。
    • 代码可维护性:可以方便地修改内部实现,而不影响外部代码,只要保持公共接口不变。

总结:不管是加_前缀还是__前缀,Python的私有化更像是一个障眼法,读者需要自己养成良好的代码习惯。


作者声明:本文用于记录和分享作者的学习心得,部分内容或示例来自豆包AI,由于本人水平有限,难免存在表达错误,欢迎交流和指教!
Copyright © 2022~2024 All rights reserved.


http://www.kler.cn/a/471324.html

相关文章:

  • Vue.js支持哪些数据可视化工具?
  • 代码随想录算法训练营第四十天 | 股票问题
  • 科普CMOS传感器的工作原理及特点
  • LRU(1)
  • C++二十三种设计模式之迭代器模式
  • 服务器等保测评审计日志功能开启(auditd)和时间校准
  • BaseCTF scxml 详解
  • 基于COT(Chain-of-Thought Prompt)的教学应用:如何通过思维链提示提升模型推理能力
  • 107周二复盘 (185)Demo打包
  • 内置AI与浏览器的开源终端Wave Terminal安装与远程连接内网服务器教程
  • C语言字符串函数详解
  • Pytest-Bdd-Playwright 系列教程(18):使用 Jinja2 钩子函数生成自定义测试报告
  • Postman接口测试04|批量运行测试用例、参数化、Mock Server、Cookie鉴权、Newman生成测试报告
  • JNPF 低代码技术架构与核心组件深度剖析
  • 大模型LLM-Prompt-TRACE
  • Springboot 读写分离
  • Ollama + FastGPT搭建本地私有企业级AI知识库 (Linux)
  • php将word转换为pdf
  • 使用Oracle的RPM包在Linux上安装MYSQL
  • 《探索 OpenCV 4.10.0:计算机视觉领域的璀璨新星》
  • docker学习记录:本地部署mongodb
  • K8S集群更新api-sever证书的SAN属性
  • 【11_只出现一次的数字】
  • flink的EventTime和Watermark
  • Couldn‘t resolve host name for http://mirrorlist.centos.org
  • 《Swift 结构体》