默认情况下,属性在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

Python基础:15私有化的更多相关文章

  1. 十五. Python基础(15)--内置函数-1

    十五. Python基础(15)--内置函数-1 1 ● eval(), exec(), compile() 执行字符串数据类型的python代码 检测#import os 'import' in c ...

  2. python基础15下_迭代器_生成器

    print(dir([])) #告诉我列表拥有的所有方法 # 双下方法 # print([1].__add__([2])) print([1]+[2]) ret = set(dir([]))& ...

  3. python基础(15):内置函数(一)

    1. 内置函数 什么是内置函数? 就是python给你提供的,拿来直接⽤的函数,比如print,input等等,截⽌到python版本3.6.2 python⼀共提供了68个内置函数.他们就是pyth ...

  4. python基础15上_迭代器_生成器

    # 迭代器和生成器 # 迭代器: # 双下方法 : 很少直接调用的方法.一般情况下,是通过其他语法触发的 # 可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir ...

  5. 『Python基础-15』递归函数 Recursion Function

    什么是递归函数 一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的.用递归过程定义的函数,称为递归函数,例如连加.连乘及阶乘等.凡是递归的函数,都是可计算的,即能行的. 递归就是一个 ...

  6. 2015/9/19 Python基础(15):变量作用域及生成器

    变量作用域标识符的作用域是定义为其声明的可应用范围,或者即是我们所说的变量可见性.也就是,我们可以在程序的那个部分去访问一个制定的标识符.全局变量与局部变量定义在函数内的变量有局部作用域,在一个模块中 ...

  7. python基础15 ---面像对象的程序设计

    面向对象的程序设计 一.面向对象的程序设计简介 1.面向对象程序设计的由来. 我们之前虽然学习过了面向过程的程序,它的核心是面向过程,一步一步的设计好了的流程,虽然极大的降低了程序的复杂度,但是一个设 ...

  8. python基础——15(加密、excel操作、ini文件操作、xml操作模块及数据格式分类)

    一.加密模块 1.有解密的加密方式(base64) #base64加密 import base64 str_encrypt = input("输入要加密的字符串:\n") base ...

  9. Day15 - Python基础15 模块学习-selectors

    本节内容 1:Python/selectors模块 2:selsect实例 1:Python/selectors模块及队列  selectors模块是可以实现IO多路复用机制: 它具有根据平台选出最佳 ...

  10. 『无为则无心』Python基础 — 15、Python流程控制语句(for循环语句)

    目录 1.for循环语法 2.for循环中的break和continue 3.循环+else结构 (1)while...else (2)while...else退出循环的方式 (3)for...els ...

随机推荐

  1. [转]文件file属性详解

    不能直接访问用户计算机中的文件,一直都是Web应用开发中的一大障碍.2000年以前,处理文件的唯一方式就是在表单中加入<input type="file">字段,仅此而 ...

  2. Codeforces 222B 数组行列交换操作

    /*做完这题发现自己好水,太伤人了.... 不过还是学到一些,如果直接暴力模拟的话肯定是TLM.. 所以要用虚拟数组来分别保存当前数组的每行没列在初始数组中的位置...*/ #include<c ...

  3. HTML:把两张图片并排(行)显示

    <table><tr><td><img src=pic1.jpg border=0></td><td><img src=p ...

  4. HTML 和 XHTML 区别

    1.初级改善 为页面添加正确的DOCTYPE 很多设计师和开发者都不知道什么是DOCTYPE,DOCTYPE有什么用. DOCTYPE是document type的简写.主要用来说明你用的XHTML或 ...

  5. 使用Docker 安装Elasticsearch、Elasticsearch-head、IK分词器 和使用

    原文:使用Docker 安装Elasticsearch.Elasticsearch-head.IK分词器 和使用 Elasticsearch的安装 一.elasticsearch的安装 1.镜像拉取 ...

  6. 洛谷 P1951 收费站_NOI导刊2009提高(2) 最短路+二分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 思路 AC代码 总结 题面 题目链接 P1951 收费站_NOI导刊2009提高(2) 其 ...

  7. loadrunner录制脚本时登录密码转md5

    在录制用户注册登录脚本时,常常会遇到web程序对用户密码进行加密处理.在很多时候采用的加密方式为MD5. 这时有两种处理方式: 一.所有用户采用同一密码 例如:每个用户名的密码都为e10adc3949 ...

  8. hdu 2444 The Accomodation of Students(二分匹配 匈牙利算法 邻接表实现)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  9. Laravel访问出错错误信息:`Warning: require(/vendor/autoload.php): failed to open stream: No such file or dire

    错误信息:`Warning: require(/http/www.mywakavLee.cn/bootstrap/../vendor/autoload.php): failed to open str ...

  10. ENSP 安装后,启动路由器提示错误41

    ENSP 安装后,启动路由器提示错误41 环境: 安装的软件清单: VirtualBox-5.2.28-130011-Win.exe WinPcap_4_1_3.exe Wireshark-x64-3 ...