Python核心编程笔记--私有化
一、私有化的实现
在Python中想定义一个类是比较简单的,比如要定义一个Person类,如下代码即可:
# -*- coding: utf-8 -*-
# __author : Demon
# date : 1/5/18 8:24 PM class Person(object):
pass p1 = Person()
当然我们也可以给类添加相应的属性,比如Person的姓名,年龄,性别等,并且在new一个Person对象后可以对这些属性进行修改,如下代码所示:
# -*- coding: utf-8 -*-
# __author : Demon
# date : 1/5/18 8:24 PM class Person(object):
def __init__(self, name, age, sex):
self.name = name #姓名
self.age = age #年龄
self.sex = sex #性别 def __str__(self): #定义直接打印Person对象,输出的内容。相当于Java中的toString()方法
return ('%s , %s , %s ' % (self.name, self.age, self.sex)) p1 = Person('Demon', 18, 'M')
print(p1) #Demon , 18 , M p1.age = 28 #修改对象的年龄
print(p1) #Demon , 28 , M
Python是面向对象的语言,我们都知道面向对象的三大特点:继承、封装和多态。而在上面的代码中,我们可以轻易地通过person. 调用属性来访问和修改值,这明显不符合面向对象中封装的思想。比如对于Person类中的年龄属性,可能比较私人,所以我们不希望可以任意的访问和修改它的值。在Java中,我们是通过private关键字来装饰属性私有,那么在Python中有没有类似的关键字呢?显然是有的,在Python中采取在变量名前加__(两个下划线)的方式来将属性私有。如下代码所示:
# -*- coding: utf-8 -*-
# __author : Demon
# date : 1/5/18 8:24 PM class Person(object):
def __init__(self, name, age, sex):
self.name = name #姓名
self.__age = age #年龄,将年龄私有
self.sex = sex #性别 def __str__(self): #定义直接打印Person对象,输出的内容。相当于Java中的toString()方法
return ('%s , %s , %s ' % (self.name, self.__age, self.sex)) p1 = Person('Demon', 18, 'M')
print(p1) #Demon , 18 , M p1.age = 28 #这里只是给p1对象动态的增加了一个age属性
print(p1) #Demon , 18 , M
print(p1.age) #
初看上面的代码,似乎感觉并没有达到私有的目的,因为我们通过p1.age还是成功地进行了赋值,程序并没有报错。其实这里是因为Python可以动态地给对象增加属性和方法,这句话相当于动态地给p1这个对象增加了一个age属性。所以在我们做了赋值操作之后,我们再次打印p1,age的值依然是18。说明我们确实已经将类里的age属性进行的私有。同理方法的私有也是一样的处理。
二、私有化的注意事项
在Python中,有几种方式来定义变量:
1、以单划线开头:这种类型的变量可以通过对象.调用,但是它表示的意思是我可以调用,但请把我视为是私有的。而且如果是通过from xxx_module import *是无法访问的,但是如果是import xxx_module的方式,则可以访问到,类对象和子类也都可以访问。
2、仅以双划线开头:这种类型的变量就是私有。但是它可以通过_类名__变量名来访问,但强烈建议不要这样做
3、以双划线开头,并以它结尾:这种类型的变量在Python中通常都表示具有特殊意义的变量,比如__init__,__str__等。所以我们在定义变量时不要这样定义
4、仅以单划线结尾:这种类型的变量是用于避免与Python关键字进行冲突所采取的一种解决办法
如下图演示访问权限效果:


三、property的使用
上面的介绍了,通过加双划线开头的方式实现了变量和方法。参照在学Java时的思路,如果想要访问私有变量,我们会给变量添加get和set方法。同样我们在Python中也是一样的处理,代码如下所示:
class Person(object):
def __init__(self, name, age, sex):
self.name = name #姓名
self.__age = age #年龄,将年龄私有
self.sex = sex #性别 def getAge(self):
return self.__age def setAge(self, age):
self.__age = age p1 = Person('Demon', 18, 'M')
print(p1.getAge()) # p1.setAge(28)
print(p1.getAge()) #
但是这样看着似乎不是很方便,每次都要调用一个方法。有没有可能像之前一样调用p1. age = 28就能直接赋值呢?显然在Python中是可以的,这就要用到property。
property的定义:

使用代码示例:
class Person(object):
def __init__(self, name, age, sex):
self.name = name #姓名
self.__age = age #年龄,将年龄私有
self.sex = sex #性别 def getAge(self):
return self.__age def setAge(self, age):
self.__age = age age = property(getAge, setAge, 'This is age property') p1 = Person('Demon', 18, 'M')
print(p1.age) # p1.age = 28
print(p1.age) #
说明:
1. property接受四个参数,分别是get, set, del, doc,前三个参数分别对应get方法,set方法,del方法,顺序不能出错。最后一个参数是doc,相当于对方法进行说明。
2. property返回一个property属性,返回值的变量名与最终对象. 后面的名称是一致的
观察上面的代码,我们仍然需要多写一行property的代码,而Python其实提供了一个更方便的实现方式来达到上述要求,即使用@property。说明如下:

示例代码如下:
class Person(object):
def __init__(self, name, age, sex):
self.name = name #姓名
self.__age = age #年龄,将年龄私有
self.sex = sex #性别 @property
def age(self): #注意方法名直接为变量名
return self.__age @age.setter #注意方法名直接为变量名
def age(self, age):
self.__age = age p1 = Person('Demon', 18, 'M')
print(p1.age) # p1.age = 28
print(p1.age) #
说明:
1. @property相当于对age方法进行了一个装饰,它使得我们能通过对象.方法名来调用对应的属性
2. @property所装饰的方法名与对象 . 调用的名称要保持一致
3. @property会生成另外的装饰器,@方法名.setter, @方法名.getter, @方法名.deleter,分别对应set, get, del方法。这里get方法用得很少,因为已经通过@property直接对应到了get方法
Python核心编程笔记--私有化的更多相关文章
- python核心编程--笔记
python核心编程--笔记 的解释器options: 1.1 –d 提供调试输出 1.2 –O 生成优化的字节码(生成.pyo文件) 1.3 –S 不导入site模块以在启动时查找pyt ...
- python核心编程--笔记(不定时跟新)(转)
的解释器options: 1.1 –d 提供调试输出 1.2 –O 生成优化的字节码(生成.pyo文件) 1.3 –S 不导入site模块以在启动时查找python路径 1.4 –v ...
- python核心编程笔记(转)
解释器options: 1.1 –d 提供调试输出 1.2 –O 生成优化的字节码(生成.pyo文件) 1.3 –S 不导入site模块以在启动时查找python路径 1.4 –v 冗 ...
- Python核心编程笔记(类)
Python并不强求你以面向对象的方式编程(与Java不同) # coding=utf8 class FooClass(object): version = 0.1 def __init__(self ...
- Python核心编程笔记--动态属性
一.动态语言与静态语言 1.1 静态语言特点: a. 在定义变量时需要指定变量的类型,根据指定的类型来确定变量所占的内存空间 b. 需要经过编译才能运行 c. 在代码编译后,运行过程不能对代码进行操作 ...
- Python核心编程笔记 第三章
3.1 语句和语法 3.1.1 注释( # ) 3.1.2 继续( \ ) 一般使用换行分隔,也就是说一行一个语句.一行过长的语句可以使用反斜杠( \ ) 分 ...
- Python核心编程笔记 第二章
2.1 程序输出:print语句 可以使用print语句显示变量的字符串表示,或者仅用变量名查看该变量的原始值. 2.2 程序输出和raw_input()内建函数 ...
- python核心编程笔记——Chapter7
Chapter7.映像和集合类型 最近临到期末,真的被各种复习,各种大作业缠住,想想已经荒废了python的学习1个月了.现在失去了昔日对python的触觉和要写简洁优雅代码的感觉,所以临到期末毅然继 ...
- python核心编程笔记
1.python的对象是通过引用传递的. 2.多元赋值: x, y = y, x
随机推荐
- BFS+数据处理 Under the Trees UVa
题意:将多叉树转化为括号表示法,每个非叶结点的正下方都有一个'|'然后下方是一排'-'和字符,恰好覆盖所有子结点的正上方,单独的一行'#'为数据的结束标志 解题思路:用gets将字符数组输入,本题不用 ...
- Cygwin-Cygwin ssh Connection closed by ::1 出错
问题描写叙述: Cygwin好不easy安装好了ssh服务,第一连接没有问题,能够显示相关信息 $ ssh localhost Last login: Sat Jul 25 09:00:30 2015 ...
- DNS解析全过程
浏览器输入一个网址.要訪问该网址必须由DNS解析出相应的server的IP地址. 对于大型站点来说,一个站点相应多台server.那么DNS解析出的可能是进行负载均衡的server的IP地址.DNS解 ...
- 前端MVC Vue2学习总结(一)——MVC与vue2概要、模板、数据绑定与综合示例
一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.Vue是框架而jQuery则是库. 1.2.AMD与CM ...
- 人工智能背景下的Office 365现状和发展趋势
作者:陈希章 发表于 2017年7月31日 引子 谈论人工智能是让人兴奋的,因为它具有让人兴奋的两大特征 -- 每个人都似乎知道一点并且以知道一点为荣,但又好像没多少人能真正讲的明白.毫无疑问,我也仅 ...
- exports 和 module.exports
首先参考一个js的示例 app.js var a = {name: 'nswbmw 1'}; var b = a; console.log(a); console.log(b); b.name = ' ...
- sqlser 2005 使用执行计划来优化你的sql
一:sqlserver 执行计划介绍 sqlserver 执行计是在sqlser manager studio 工具中打开,是检查一条sql执行效率的工具.建议配合SET STATISTICS ...
- springboot+多数据源配置
作者:纯洁的微笑 出处:http://www.ityouknow.com/ 起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多 ...
- 理解Babel是如何编译JS代码的及理解抽象语法树(AST)
Babel是如何编译JS代码的及理解抽象语法树(AST) 1. Babel的作用是? 很多浏览器目前还不支持ES6的代码,但是我们可以通过Babel将ES6的代码转译成ES5代码,让所有的浏览器都 ...
- 让intellij idea 14 支持ES6语法
用eclipse做前端开发,用到了webpack,结果各种依赖导致软件卡的一比,简直不能动!虽然在同事的帮忙下,修改了一下配置,但仍然卡的没脾气.改用intellij idea 14解决了卡的问题,但 ...