Private Variable and Private Method - Python 私有变量 和 私有方法
Private Variable and Private Method
Python 不象 Java 那样, 通过 private 关键字创建私有属性, python 通过更简洁的实现了'私有属性', 从而避免了子类意外覆盖私有属性.
举个例子来说, 现在编写一下儿名字叫 Robot 的类,并实现了一个名字为 fighting 的属性。
接着又人编写了一个叫 Camaro 的类, 并继承了 Robot 类, 并在其中构造了 fighting 的属性, 这个时候 Robot 的 fighting 属性被覆盖了.
而恰巧 Robot 类的编写者的意图是 - 不允许所有 Robot 的子类访问 fighting(可能为了世界和平), 显然 Camaro 这个子类破坏了这一点. 为了避免这种情况, Robot 类的编写者可以以 __fighting (或者 __fighting_) 来命名要私自属性(声明成成私有属性).
这时 Python 的解释器会该属性 '修饰' 后再添加到 __dict__ 属性中, 该例中会变成 _Robot__fighting, 而不是 __fighting (原形式)
Python 的这种特性被称为 name mangling.
注, 名称改写(name mangling),Python 解释器在运行时自动把私有属性 __x (或 __x_)重命名为 _MyClass__X (或 _MyClass__X_)
以上文字所对应的例子,
class Robot(object):
__RB = 3
__RB_ = 5
def __fighting(self):
print('This is \'_MyClass__X\' format') def __fighting_(self):
print('This is \'_MyClass__X_\' format') def func(self):
print('Called via - A') class Camaro(Robot):
def func(self):
print('Called via - B') if __name__ == "__main__":
print(Robot.__dict__) #
a = Camaro()
a.func() #
print(Camaro.__mro__) #
super(Camaro,a).func() #
a._Robot__fighting() #
a._Robot__fighting_() #
a.__fighting # Output,
{'__module__': '__main__', '_Robot__RB': 3, '_Robot__RB_': 5,'_Robot__fighting': <function Robot.__fighting at 0x039C6300>,
'_Robot__fighting_': <function Robot.__fighting_ at 0x039C62B8>,
'func': <function Robot.func at 0x039C6270>, ...}
#1 |^ 添加到 __dict__ 中的是 '_MyClass__X' 或者 '_MyClass__X_' - name mangling
Called via - B #2 子类的中方法覆盖了父类中的'同名'方法
(<class '__main__.Camaro'>, <class '__main__.Robot'>, <class 'object'>) #3 MRO __mro__
Called via - A #3 super 指的并不一定是'父类', 而是 MRO 中的'下一个' ******
This is '_MyClass__X' format #4 name mangling ; 知道 name mangling 规则后 可以 hack 私有属性
This is '_MyClass__X_' format #4 name mangling ; 知道 name mangling 规则后 可以 hack 私有属性
a.__fighting
AttributeError: 'Camaro' object has no attribute '__fighting' #5 常规方法调用属性报错(AttributeError), 因为 __dict__ 没有相应属性
Private Variable and Private Method - Python 私有变量 和 私有方法的更多相关文章
- python 类的私有变量和私有方法
#!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2017/11/08 8:46 # @Author : lijunjiang # @Fil ...
- Python类中的 私有变量和私有方法
默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量.在python中定义私有变量只需要在变量 ...
- Python保护变量、私有变量、私有方法
保护变量.私有变量.私有方法介绍: _xxx: 单下划线开头叫保护变量,意思是只有类对象和子类对象自己能访问到这些变量,此变量不能通过from XXX import xxx 导入: __xxx : 双 ...
- 反射工具类.提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,被AOP过的真实类等工具函数.java
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.ap ...
- iOS 学习如何声明私有变量和私有方法
私有变量 首先来说 OC 中没有绝对的私有变量,这么说基于两点原因: 1可修改: 通过KVC 键值编码 来修改私有成员变量的值 2可读取 : 通过底层runtime 获取实例变量Ivar 对应 ...
- js静态私有变量(将方法变成原型模式,被所有实例共享,而方法操作变量,故变量是静态)
js静态私有变量(将方法变成原型模式,被所有实例共享,而方法操作变量,故变量是静态) 一.总结 1.js函数中的private和public:js函数中的私有变量 var 变量名,公有变量 this. ...
- JavaScript 执行环境(执行上下文) 变量对象 作用域链 上下文 块级作用域 私有变量和特权方法
总结自<高程三>第四章 理解Javascript_12_执行模型浅析 JS的执行环境与作用域 javascript高级程序第三版学习笔记[执行环境.作用域] 在javascript ...
- 第七章 函数表达式和函数声明,关于this对象 ,私有作用域(function(){})() ,私有变量和特权方法
一:函数表达式和函数声明 1:函数声明和函数表达式的区别 ①函数声明不需要分号结尾 ②函数声明有函数提升的特点 ③函数声明后面不能跟圆括号直接调用,因为javascript将function关键字当作 ...
- [python] 私有变量和私有方法
1.在Python中要想定义的方法或者变量只在类内部使用不被外部调用,可以在方法和变量前面加 两个 下划线 #-*- coding:utf-8 -*- class A(object): name = ...
随机推荐
- Could not find iPhone 6 simulator
最近原来的老项目有点问题需要处理一下,运行启动命令,就报了如下错误,提示找不到iPhone 6 模拟器. react-native run-ios Owaiss-Mac:pdm owaisahmed$ ...
- 79.纯 CSS 创作单元素麦当劳金拱门 Logo(原文)
1. 效果图: 效果地址:https://codepen.io/flyingliao/pen/JgavjX 原理:m是伪元素::before弄出来的,::after遮挡中间下方一小块. 感想:学到一个 ...
- SPFA判负环模板
void DFS_SPFA(int u){ if(flag) return; vis[u]=true; for(int i=head[u];i;i=edges[i].nxt){ if(fl ...
- NPOI导出Excel生成多个sheet
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- 关于爬虫的日常复习(18)——scrapy系列3
- Mysql.新建数据库和用户
//建立数据库 drop database if exists 你的db名; create database 你的db名 CHARACTER SET utf8 COLLATE utf8_general ...
- Java中整数值的4中表示方式u
Java中整数值有4中表示方式:十进制.二进制.八进制和十六进制,其中二进制的整数以0b或0B开头:八进制的整数以0开头: 十六进制的整数以0x或0X开头,其中10-15分别以a-f(此处的a-f不区 ...
- rabbitmq 实现延迟队列的两种方式
原文地址:https://blog.csdn.net/u014308482/article/details/53036770 ps: 文章里面延迟队列=延时队列 什么是延迟队列 延迟队列存储的对象肯定 ...
- Linux起源
Linux起源 操作系统出现时间线: Unix1970年诞生 ,71年用C语言重写 Apple II 诞生于1976年 window诞生于1985年 Linux诞生于1991年,由大学生Linus T ...
- Math.Atan2 方法
返回正切值为两个指定数字的商的角度. public static double Atan2 ( double y, double x ) 参数 y 点的 y 坐标. x 点的 x 坐标. 返回值 角 ...