Python类中的 私有变量和私有方法
默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量。
在python中定义私有变量只需要在变量名或函数名前加上 ”__“两个下划线,那么这个函数或变量就是私有的了。
在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername,也就是说,类的内部定义中,
所有以双下划线开始的名字都被"翻译"成前面加上单下划线和类名的形式。
例如:为了保证不能在class之外访问私有变量,Python会在类的内部自动的把我们定义的__spam私有变量的名字替换成为
_classname__spam(注意,classname前面是一个下划线,spam前是两个下划线),因此,用户在外部访问__spam的时候就会
提示找不到相应的变量。 python中的私有变量和私有方法仍然是可以访问的;访问方法如下:
私有变量:实例._类名__变量名
私有方法:实例._类名__方法名()
其实,Python并没有真正的私有化支持,但可用下划线得到伪私有。 尽量避免定义以下划线开头的变量!
(1)_xxx "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量,
需通过类提供的接口进行访问;不能用'from module import *'导入
(2)__xxx 类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。),
" 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。
(3)__xxx__ 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 __init__()代表类的构造函数。
下面我们看几个例子:
【1】
- class A(object):
- def __init__(self):
- self.__data=[] #翻译成 self._A__data=[]
- def add(self,item):
- self.__data.append(item) #翻译成 self._A__data.append(item)
- def printData(self):
- print self.__data #翻译成 self._A__data
- a=A()
- a.add('hello')
- a.add('python')
- a.printData()
- #print a.__data #外界不能访问私有变量 AttributeError: 'A' object has no attribute '__data'
- print a._A__data #通过这种方式,在外面也能够访问“私有”变量;这一点在调试中是比较有用的!
运行结果是:
['hello', 'python']
['hello', 'python']
【2】
获取实例的所有属性 print a.__dict__
获取实例的所有属性和方法 print dir(a)
- class A():
- def __init__(self):
- self.__name='python' #私有变量,翻译成 self._A__name='python'
- def __say(self): #私有方法,翻译成 def _A__say(self)
- print self.__name #翻译成 self._A__name
- a=A()
- #print a.__name #访问私有属性,报错!AttributeError: A instance has no attribute '__name'
- print a.__dict__ #查询出实例a的属性的集合
- print a._A__name #这样,就可以访问私有变量了
- #a.__say()#调用私有方法,报错。AttributeError: A instance has no attribute '__say'
- print dir(a)#获取实例的所有属性和方法
- a._A__say() #这样,就可以调用私有方法了
运行结果:
{'_A__name': 'python'}
python
['_A__name', '_A__say', '__doc__', '__init__', '__module__']
python
从上面看来,python还是非常的灵活,它的oop没有做到真正的不能访问,只是一种约定让大家去遵守,
比如大家都用self来代表类里的当前对象,其实,我们也可以用其它的,只是大家习惯了用self 。
【3】小漏洞:派生类和基类取相同的名字就可以使用基类的私有变量
- class A():
- def __init__(self):
- self.__name='python' #翻译成self._A__name='python'
- class B(A):
- def func(self):
- print self.__name #翻译成print self._B__name
- instance=B()
- #instance.func()#报错:AttributeError: B instance has no attribute '_B__name'
- print instance.__dict__
- print instance._A__name
运行结果:
{'_A__name': 'python'}
python
- class A():
- def __init__(self):
- self.__name='python' #翻译成self._A__name='python'
- class A(A): #派生类和基类取相同的名字就可以使用基类的私有变量。
- def func(self):
- print self.__name #翻译成print self._A__name
- instance=A()
- instance.func()
运行结果:
python
Python类中的 私有变量和私有方法的更多相关文章
- 第7.10节 Python类中的实例变量定义与使用
一. 引言 在前面章节已经引入介绍了类变量和实例变量,类体中定义的变量为类变量,默认属于类本身,实例变量是实例方法中定义的self对象的变量,对于每个实例都是独有数据,而类变量是该类所有实例共享 ...
- 第8.11节 Python类中记录实例变量属性的特殊变量__dict__
一. 语法释义 调用方法:实例. __dict__属性 __dict__属性返回的是实例对象中当前已经定义的所有自定义实例变量的名和值,用字典存储,每个元素为一个"实例变量名:值" ...
- 第8章 Python类中常用的特殊变量和方法目录
第8章 Python类中常用的特殊变量和方法 第8.1节 Python类的构造方法__init__深入剖析:语法释义 第8.2节 Python类的__init__方法深入剖析:构造方法案例详解 第8. ...
- python 类的私有变量和私有方法
#!/usr/bin/env python # -*- coding:utf-8 -*- # @Time : 2017/11/08 8:46 # @Author : lijunjiang # @Fil ...
- 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘
孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了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 ...
- 编写Java程序,实现对兵营类的封装,将兵营类中的所有属性设置为私有访问权限,方法设置为公有访问权限
返回本章节 返回作业目录 需求说明: 实现对兵营类的封装 将兵营类中的所有属性设置为私有访问权限. 将兵营类中所有属性的赋值方法设置为公有访问权限. 要求兵营名称的长度在4-8位之间. 要求兵营士兵的 ...
- 第八章 Python类中常用的特殊变量和方法
上章花了近三十章节介绍类的知识,本章估计内容也比较多,讲完这些,其实还有更多.为什么这么多类有关的知识呢,这是因为在Python里面一切皆对象,就连整型.浮点数.字符串这些比较常规的类型都是作为类来实 ...
随机推荐
- 第十四章 netlink机制--基于Linux3.10【转】
本文转载自:http://blog.csdn.net/shichaog/article/details/44682613 Netlink基于网络的消息机制,能够让用户和内核空间进行通信,12.3节提到 ...
- 深度学习的seq2seq模型——本质是LSTM,训练过程是使得所有样本的p(y1,...,yT‘|x1,...,xT)概率之和最大
from:https://baijiahao.baidu.com/s?id=1584177164196579663&wfr=spider&for=pc seq2seq模型是以编码(En ...
- bzoj 1601 灌水
题目大意: 决定把水灌到n块农田,农田被数字1到n标记 把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库 建造一个水库需要花费wi,连接两块土地需要花费Pij. 计算所需的最少代价 ...
- 【POJ 3974】 Palindrome
[题目链接] http://poj.org/problem?id=3974 [算法] 解法1 : 字符串哈希 我们可以分别考虑奇回文子串和偶回文子串,从前往后扫描字符串,然后二分答案,检验可以用哈希 ...
- POJ1061 青蛙的约会 exgcd
这个题虽然很简单,但是有一个比较坑的地方,就是gcd不一定是1,有可能是别的数.所以不能return 1,而是return a; 题干: Description 两只青蛙在网上相识了,它们聊得很开心, ...
- django - request.POST和request.body获取值时出现的情况
django request.POST / request.body 当request.POST没有值 需要考虑下面两个要求 1.如果请求头中的: Content-Type: application/ ...
- native2ascii运用
1.native2ascii命令行的格式 native2ascii -[option] [inputfile [outputfile]] 说明: -[option]:表示命令开关,有两个选项可供选择: ...
- Java中多个线程交替循环执行
有些时候面试官经常会问,两个线程怎么交替执行呀,如果是三个线程,又怎么交替执行呀,这种问题一般人还真不一定能回答上来.多线程这块如果理解的不好,学起来是很吃力的,更别说面试了.下面我们就来剖析一下怎么 ...
- 在vue项目npm run build后,index.html中引入css和js 报MIME type问题
问题: 1.在vue项目中,build打包后,index页面打开会报错, MIME type ('text/html') ;报错内容:because its MIME type ('text/html ...
- HyperLedger Fabric部署与链码解读
1.Fabric简介 Fabric是超级账本中的一个项目,用以推进区块链技术.和其他区块链类似,它也有一个账本,使用智能合约,且是一个参与者可以分别管理自身交易的系统.它是一个联盟链.Fabric与其 ...