为什么设计私有变量

大多数 Python 代码都遵循这样一个约定:带有一个下划线的名称 (例如: _spam) 应该被当作是 API 的非公有部分 (无论它是函数、方法或是数据成员)。

为了保证对于类私有成员的有效使用(例如避免名称与派生类所定义的名称相冲突),设立了名称改写(name mangling)机制。 任何形式为 __spam 的标识符(至少带有两个前缀下划线,至多一个后缀下划线)的文本将被替换为 _classname__spam,其中 classname 为去除了前缀下划线的当前类名称。 这种改写不考虑标识符的句法位置,只要它出现在类定义内部就会进行。

名称改写有助于让子类重载方法而不破坏类内方法调用。例如:

class Mapping:def __init__(self, iterable):self.items_list = []self.__update(iterable)def update(self, iterable):for item in iterable:self.items_list.append(item)__update = update   # private copy of original update() methodclass MappingSubclass(Mapping):def update(self, keys, values):# provides new signature for update()# but does not break __init__()for item in zip(keys, values):self.items_list.append(item)

上面的示例即使在 MappingSubclass 引入了一个 __update 标识符的情况下也不会出错,因为它会在 Mapping 类中被替换为 _Mapping_update 而在 MappingSubclass 中被替换为_MappingSubclass _update 。改写规则的设计主要是为了避免意外冲突;访问或修改被视为私有的变量仍然是可能的。

变量的定义

xx:公有变量

_xx:单下划线,私有化属性或方法,类对象和子类可以访问,from somemodule import *禁止导入

__xx:双下划线,私有化属性或方法,无法在外部直接访问(名字改写不能访问)

__xx__:双前后下划线,系统定义名字(用户避免使用)

xx_:单下划线,用于避免与Python关键词的冲突

示例1:对于变量的访问

class student(object):def __init__(self):self.num = 10self._name = "wang"self.__grade = 30stu = student()
print(stu.num)              # 10
print(stu._name)            # wang
# print(stu.__grade)        # error
print(stu._student__grade)  # 30stu.__grade = 40
print(stu.__grade)          # 40
print(stu._student__grade)  # 30
stu._student__grade = 50
print(stu.__grade)          # 40
print(stu._student__grade)  # 50

尤其注意最后六行,可以看到名称改写对私有变量的影响。

可以看出,不能在外部直接访问双下划线的私有变量,而用改写后的名字即可访问,因此可知在 Python 中并没有严格意义上的私有变量。在编程的时候应该注意这一点。

示例2:从外部导入对私有变量的影响

_variable 类型的属性或方法不能通过 from module import * 语句导入,能够通过 import module 语句导入

# test.pynum = 10
_name = "wang"
__grade = 30def get_num():print("get_num")def _get_name():print("get_name")def __get_grade():print("get_grade")
from test import *print(num)                 # 10
# print(_name)             # error
# print(__grade)           # errorget_num()                  # get_num
# _get_name()              # error
# __get_grade()            # error
import testprint(test.num)                 # 10
print(test._name)               # wang
print(test.__grade)             # 30test.get_num()                  # get_num
test._get_name()                # get_name
test.__get_grade()              # get_grade

可知,利用 import ... 和 from module import ... 导入后,对于变量的引用方式也是有区别,具体可以看这篇文章。

也可以通过装饰器来调用私有变量,详细的可以看这篇文章。

参考资料:

1. Python官方文档:https://docs.python.org/zh-cn/3.7/

2. 博客:https://www.cnblogs.com/semon-code/p/8242062.html

Python 中私有变量的定义和用法相关推荐

  1. Python中私有变量和私有方法芳

    Python中要想定义的方法或者变量只能在类内部使用不被外部使用,可以在方法和变量前面加两个下划线,让其变为私有方法或私有变量.类外部可以通过 "_类名__私有属性(方法)名" 访 ...

  2. python私有属性怎么定义_Python中私有属性的定义方式

    Python没有类似于Java的private关键字, 但也可以为类定义私有属性. 只需将属性命名变为以__开头, 例如 __field. 示例代码: class Vector2D(object): ...

  3. python中特殊变量-python list每三个分成一组python中星号变量的几种特殊用法

    在Python中星号除了用于乘法数值运算和幂运算外,还有一种特殊的用法"在变量前添加单个星号或两个星号",实现多参数的传入或变量的拆解,本文将详细介绍"星号参数" ...

  4. python中星号变量传参的几种特殊用法

    python中星号变量的几种特殊用法 原文:https://www.jianshu.com/p/77acbc1b0d3e 在Python中星号除了用于乘法数值运算和幂运算外,还有一种特殊的用法&quo ...

  5. python中 是什么类型_浅谈python中的变量默认是什么类型

    浅谈python中的变量默认是什么类型 1.type(变量名),输出的结果就是变量的类型: 例如 >>> type(6) 2.在Python里面变量在声明时,不需要指定变量的类型,变 ...

  6. python中none算变量吗_在python中对变量判断是否为None的三种方法总结

    三种主要的写法有: 第一种:if X is None; 第二种:if not X: 当X为None,  False, 空字符串"", 0, 空列表[], 空字典{}, 空元组()这 ...

  7. python中的变量是动态类型的什么意思_Python零基础入门(一):对Python的简单认识...

    点击蓝字 关注浅韵 一起划水 写在前面 期末考试告一段落之后,这个公众号又活了. 漫长的假期,想玩也是肯定的,但是发现自己想学的东西也很多,想写的东西也很多,所以给自己来了一个假期整活计划. 在这个假 ...

  8. python类私有变量

    python类,专栏总目录: 1.python面向对象编程class 2.python类多重继承 3.python类私有变量 4.python包私有变量__all__ 5.python类枚举 1.类l ...

  9. Python中yield和yield from的用法

    yield 后面接的是 future 对象 调用方 委托生成器 yield from 直接给出循环后的结果 yield from 委托者和子生成器直接通信 yield from 直接处理stopIte ...

最新文章

  1. How I Hacked 40 Websites in 7 minutes
  2. Middleware trace tool SMWT
  3. ios mysql 创建不同的用户表_iOS中数据库-创建表-增删改查数据-基础语法
  4. [Java][JavaScript]字符串数组与字符串之间的互转(join/split)(转)
  5. logisim无法打开解决办法
  6. OJ1074: 百钱买百鸡(C语言)
  7. java 协议这个概念_java网络协议概念是什么?
  8. [2019杭电多校第二场][hdu6599]I Love Palindrome String(回文自动机hash)
  9. 排序算法专题-希尔排序
  10. 高手常用的15 种 SQL 优化
  11. 第四届“泰迪杯”数据分析技能赛通知
  12. 单片机c语言实习报告,单片机实习心得
  13. java中的quartz_java 中对Quartz表达式的执行
  14. 发电子邮件怎么发,手机发电子邮件教程来了
  15. Vray和PS的冬景效果图制作教程蓝海创意云渲染
  16. 神经管理学是什么样的学科?
  17. 文章采集软件怎么采集文章?
  18. 传智健康day04 预约管理-套餐管理
  19. 数据资源丨原始数据哪里找?这些网站要用好!(建议收藏)
  20. moment获取时间

热门文章

  1. 鼠标悬浮事件 -jQuery hover()方法(layer.js)(layer.tips)
  2. html鼠标触发显示悬浮窗,JS事件之鼠标悬浮窗(鼠标悬浮窗抖动问题的解决)
  3. linux tar.xz 解压命令,tar.xz后缀文件创建和解压命令
  4. React通过url传参和通过路由传参
  5. Java访问Hadoop实践
  6. Linux下的查找命令合集(which/whereis/locate/find)
  7. Linux五个查找命令
  8. Vue的生命周期钩子函数
  9. 瓦尔登湖--读后精选片段
  10. 使用@Value读取yml配置文件编译报错