python(57):私有变量,代码块
Python类中双下划线的私有成员(私有函数,私有变量)
一、Python中默认的成员函数、成员变量都是公开的(public),而且python中没有类似public、private等关键词来修饰成员函数,成员变量。
在python中定义私有变量只需要在变量名或函数名前加上 "__" (两个下划线),那么这个函数或变量就会成为私有的了。
在内部,python使用一种 name mangling 技术,将__membername替换成 _classname__membername,所以你在外部使用原来的私有成员的名字时,会提示找不到。
命名混淆意在给出一个在类中定义"私有"实例变量和方法的简单途径,避免派生类的实例变量定义产生问题,或者与外界代码中的变量搞混。
要注意的是混淆规则主要目的在于避免意外错误,被认作为私有的变量仍然有可能被访问或修改(使用_classname__membername),在特定的场合它也是有用的,比如调试的时候。
【示例代码】
# -*- coding: utf-8 -*-
class Test(object):
def __init__(self):
super(Test, self).__init__()
self.__member = 99
def __method(self):
print "Test.__method"
if __name__ == '__main__':
t = Test()
print dir(t)
#t.__method() # AttributeError: 'Test' object has no attribute '__method'
#print t.__member # AttributeError: 'Test' object has no attribute '__member'
t._Test__method() # 使用Python更改之后的函数名依然可以访问到"私有"函数
print t._Test__member # 使用Python更改之后的变量名依然可以访问到"私有"变量
'''
['_Test__member', '_Test__method', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
Test.__method
99
'''
可以看到在dir里面多的不是__member和__method,而是_Test__member和_Test__method。并且可以通过_Test__member和_Test__method访问原来类里面的成员变量和成员函数。
二、单下划线开头的成员变量和成员函数,其实就是public的,不等同于protected属性。
【示例代码】
# -*- coding: utf-8 -*-
class Test(object):
def __init__(self):
super(Test, self).__init__()
self.__member = 88
self._member = 99
def __method(self):
print "Test.__method"
def _method(self):
print "Test._method"
class TestDerived(Test):
def __init__(self):
super(TestDerived, self).__init__()
def test(self):
#print self.__member # AttributeError: 'TestDerived' object has no attribute '_TestDerived__member'
#self.__method() # AttributeError: 'TestDerived' object has no attribute '_TestDerived__method'
print self._member
self._method()
if __name__ == '__main__':
td = TestDerived()
print dir(td)
td.test()
#print td.__member # AttributeError: 'TestDerived' object has no attribute '__member'
#td.__method() # AttributeError: 'TestDerived' object has no attribute '__method'
print td._member # 外部可以直接访问单下划线开头的成员变量
td._method() # 外部可以直接访问单下划线开头的成员函数
'''
['_Test__member', '_Test__method', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_member','_method', 'test']
99
Test._method
99
Test._method
'''
无论是单下划线还是双下划线开头的成员,都是希望外部程序开发者不要直接使用这些成员变量和这些成员函数,只是双下划线从语法上能够更直接的避免错误的使用,但是如果按照 _类名__成员名 则依然可以访问到。单下划线的在动态调试时可能会方便一些,只要项目组的人都遵守下划线开头的成员不直接使用,那使用单下划线或许会更好。
if __name__ == "__main__":
在继续学习新东西之前, 有几点重要的观察结果。 首先, if 表达式无需使用圆括号括起来。 其次, if 语句以冒号结束, 随后跟随的是 缩进代码。
与 C 一样, Python 使用 == 做比较, 使用 = 做赋值。 与 C 不一样, Python 不支持行内赋值, 所以不会出现想要进行比较却意外地出现赋值的情况。
那么为什么说这个特殊的 if 语句是一个技巧呢?模块是对象, 并且所有的模块都有一个内置属性 __name__。一个模块的 __name__ 的值要看您如何应用模块。如果 import 模块, 那么 __name__的值通常为模块的文件名, 不带路径或者文件扩展名。但是您也可以像一个标准的程序一样直接运行模块, 在这种情况下 __name__的值将是一个特别的缺省值, __main__。
>>> import odbchelper
>>> odbchelper.__name__
'odbchelper'
一旦了解到这一点, 您可以在模块内部为您的模块设计一个测试套件, 在其中加入这个 if 语句。当您直接运行模块, __name__ 的值是 __main__, 所以测试套件执行。当您导入模块, __name__的值就是别的东西了, 所以测试套件被忽略。这样使得在将新的模块集成到一个大程序之前开发和调试容易多了.
在 MacPython 上, 需要一个额外的步聚来使得 if __name__ 技巧有效。 点击窗口右上角的黑色三角, 弹出模块的属性菜单, 确认 Run as __main__ 被选中。
python(57):私有变量,代码块的更多相关文章
- Python的私有变量与装饰器@property的用法
Python的私有变量是在变量前面加上双横杠(例如:__test)来标识, Python私有变量只能在类内部使用,不被外部调用,且当变量被标记为私有后,调用时需再变量的前端插入类名,在类名前添加一个下 ...
- [深入Python]Python的私有变量
Python没有真正的私有变量.内部实现上,是将私有变量进程了转化,规则是:_<类名><私有变量> 下面的小技巧可以获取私有变量: class Test(object): de ...
- Python访问私有变量
代码: class Counter(object): __secount=0 publicfs=0 def getcount(self): self.__secount+=1 self.publicf ...
- python的私有变量解析
在内的内部定义并使用,外部无法訪问,以双下划线作为前作,定义后被python转为 _classname__变量名了 ------------------------------------------ ...
- [py]python的私有变量
参考 python中并没有真正意义上的私有成员,它提供了在成员前面添加双下划线的方法来模拟类似功能.具体来说: _xxx 表示模块级别的私有变量或函数 __xxx 表示类的私有变量或函数 这被称为na ...
- python基础-私有变量和方法
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问 __priva ...
- python重要的函数代码块
注意:现在python3.3.5中print打印语句有了新写法: 1. python指定生成随机数 >>> import random >>> >>&g ...
- python如何计算程序(代码块)的运行时间?
1.引入time模块 2.调用time模块的time()函数 :用来获取当前的时间,返回的单位是秒 # 引入一个time模块, * 表示time模块的所有功能, # 作用: 可以统计程序运行的时间 f ...
- python下载图片的代码块
import urllib.requestimgurl="https://ss3.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/si ...
随机推荐
- Debug 路漫漫-05
Debug 路漫漫-05: 1.使用这种方式计算 AUC 指标,结果出来居然是 NAN, —— 分母为(M*N),M或者N必有一个为0 了.(nan出现的情况绝大部分是分母出现0了) 若分子为0的 ...
- Soapui groovy 加载外部property文件
proFile = "c:\\test.properties" log.info proFile props = new java.util.Properties() props. ...
- C/C++查找一定范围内的素数(筛法)
本文转自于:http://dalu.blogbus.com/logs/37977984.html 由于一个合数总是可以分解成若干个质数的乘积,那么如果把质数(最初只知道2是质数)的倍数都去掉,那么剩下 ...
- Spring事务异常回滚,捕获异常不抛出就不会回滚
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...
- 【HTML】网页中如何让DIV在网页滚动到特定位置时出现
用js或者jquery比较好实现.但你要知道,滚动到哪个特定位置,例如滚动到一个标题h3那显示这个div,那么可以用jquery算这个h3距离网页顶部的距离:$("h3").off ...
- 【Linux】字符转换命令join
join 看字面上的意义 (加入/参加) 就可以知道,他是在处理两个文件之间的数据,而且,主要是在处理『两个文件当中,有 "相同数据" 的那一行,才将他加在一起』的意思.我们利用底 ...
- High-speed Charting Control--MFC绘制图表(折线图、饼图、柱形图)控件
原文地址:https://www.codeproject.com/articles/14075/high-speed-charting-control 本文翻译在CodeProject上的介绍(主要还 ...
- Set up development environment for apps for SharePoint 2013
SharePoint 2013 support app development pattern.An app for SharePoint is small and isolate applicati ...
- sessionId与cookie 的关系(百度文库)
这篇文档讲的很清楚,推荐阅读 http://wenku.baidu.com/view/2ecf0b350b4c2e3f572763d1.html
- webpack 4.0的一些小坑
一.需要指定开发模式还是生产模式,需要改动两个地方: 1.package.json 中加入 --mode development "scripts": { "dev&qu ...