默认情况下,属性在Python 中都是“public”。

1:双下划线(__)

Python 为类元素(属性和方法)的私有性提供初步的形式。由双下划线开始的属性在运行时被“混淆”,所以直接访问是不允许的。实际上,会在名字前面加上下划线和类名。

class pubpri(object):
def __init__(self, num):
self._num= num
self.__num = num
self.__num__= num
self.pubnum = num >>> n1 = pubpri(3) >>> n1._num
3 >>> n1.__num__
3 >>> n1.pubnum
3 >>>n1.__num
Traceback(most recent call last):
File"<stdin>", line 1, in <module>
AttributeError:'pubpri' object has no attribute '__num' >>>n1._pubpri__num
3

尽管这样做提供了某种层次上的私有化,但算法处于公共域中,并且很容易被破解。

这种名字混淆的另一个目的,是为了保护__XXX 变量不与父类名字空间相冲突。如果在类中有一个__XXX 属性,它将不会被其子类中的__XXX 属性覆盖。使用__XXX,子类的代码就可以安全地使用__XXX,而不必担心它会影响到父类中的__XXX。

2:单下划线(_)

在一个模块中以单下划线开头的变量和函数被默认当作内部函数,如果使用from a_module import * 导入时,这部分变量和函数不会被导入。不过值得注意的是,如果使用 import a_module 这样导入模块,仍然可以用a_module._some_var 这样的形式访问到这样的对象。比如,假设test.py内容如下:

import  sys
_modulenum = 3
__modulenum = 3
__modulenum__ = 3
pubnum = 3 def _fun():
print 'this is',sys._getframe().f_code.co_name def __fun():
print'this is ', sys._getframe().f_code.co_name def __fun__():
print'this is ', sys._getframe().f_code.co_name def fun():
print'this is ', sys._getframe().f_code.co_name >>> from test import *
>>>_modulenum
...
NameError: name'_modulenum' is not defined >>>__modulenum
...
NameError: name'__modulenum' is not defined >>>__modulenum__
...
NameError: name'__modulenum__' is not defined >>>pubnum
3 >>> _fun()
...
NameError: name'_fun' is not defined >>> __fun()
...
NameError: name'__fun' is not defined >>>__fun__()
...
NameError: name'__fun__' is not defined >>> fun()
this is fun >>> import test
>>>test._modulenum
3 >>>test.__modulenum
3 >>>test.__modulenum__
3 >>>test.pubnum
3 >>>test._fun()
this is _fun >>>test.__fun()
this is __fun >>>test.__fun__()
this is __fun__ >>>test.fun()
this is fun

双下划线开头双下划线结尾的是一些 Python 的特殊对象,如类成员的 __init__、__del__、__add__、__getitem__等。 Python 官方推荐永远不要将这样的命名方式应用于自己的变量或函数,而是按照文档说明来使用。

注意,私有化都是针对外部而言,在类内部,依然可以使用正常的访问方式,在类的外部就必须进行“混淆”了。比如:

class test(object):
__cversion =1.1 def __init__(self):
self.__iversion = 1.2 def fun(self):
print self.__iversion
print test.__cversion
print self._test__iversion
print self._test__cversion >>> from test import test
>>> t1 = test()
>>> t1.fun()
1.2
1.1
1.2
1.1 >>> t1.__iversion
Traceback (most recent call last):
File"<stdin>", line 1, in <module>
AttributeError: 'test' object has no attribute'__iversion' >>> t1._test__iversion
1.2 >>> t1.__cversion
Traceback (most recent call last):
File"<stdin>", line 1, in <module>
AttributeError: 'test' object has no attribute'__cversion' >>> t1._test__cversion
1.1

参考:

http://www.zhihu.com/question/19754941

最新文章

  1. 管理分支:git branch
  2. 关于scrollWidth,clientWidth,offsetWidth
  3. Windows10 如何删掉内置的 skype ?
  4. 如何做出header,footer固定定位后让main主体部分可以滑动,在微信浏览器中滑动到最后不出现黑边的情况
  5. php源码之计算两个文件的相对路径
  6. 【分享】iTOP-4412开发板使用之初体验[多图]
  7. 【bzoj1012】[JSOI2008]最大数maxnumber
  8. Careercup - Facebook面试题 - 6685828805820416
  9. POJ2104 k-th number 划分树
  10. Drawable与Bitmap 自定义
  11. 理解java的三大特性之多态(三)
  12. pdf.js在国际化的时候,显示不了中文的解决办法
  13. tcp netstat用法 TIME_WAIT状态解析 MTU以及MSS
  14. linux shell 中的 2&gt;&amp;1 用法说明
  15. 大数据 --&gt; 安装Hadoop-单机模式(1)
  16. Atomic in Redis
  17. Update openssh7.9 on centos6
  18. ansible 问题
  19. [转][html]设置IIS 默认页
  20. bitmap过大无法显示图片的问题 - z

热门文章

  1. tyvj 1423 GF和猫咪的玩具
  2. zoj2562 反素数
  3. jQuery 源码解析(二十九) 样式操作模块 尺寸详解
  4. Spring这棵大树
  5. Redis → Windows下搭建redis集群
  6. IE9没有内置鼠标手势,还要自己写
  7. 阿里毕玄:来测试下你的Java编程能力
  8. 二维vector基本使用
  9. pip 异常问题
  10. 杨柳絮-Info:阜阳市多举措治理杨柳絮问题