博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python核心编程笔记--私有化
阅读量:6535 次
发布时间:2019-06-24

本文共 3734 字,大约阅读时间需要 12 分钟。

一、私有化的实现

在Python中想定义一个类是比较简单的,比如要定义一个Person类,如下代码即可:

# -*- coding: utf-8 -*-# __author : Demon# date : 1/5/18 8:24 PMclass Person(object):    passp1 = Person()

当然我们也可以给类添加相应的属性,比如Person的姓名,年龄,性别等,并且在new一个Person对象后可以对这些属性进行修改,如下代码所示:

# -*- coding: utf-8 -*-# __author : Demon# date : 1/5/18 8:24 PMclass 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 PMclass 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 , Mp1.age = 28 #这里只是给p1对象动态的增加了一个age属性print(p1) #Demon , 18 , Mprint(p1.age) #28

初看上面的代码,似乎感觉并没有达到私有的目的,因为我们通过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 = agep1 = Person('Demon', 18, 'M')print(p1.getAge()) #18p1.setAge(28)print(p1.getAge()) #28

但是这样看着似乎不是很方便,每次都要调用一个方法。有没有可能像之前一样调用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) #18p1.age = 28print(p1.age) #28

说明:

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 = agep1 = Person('Demon', 18, 'M')print(p1.age) #18p1.age = 28print(p1.age) #28

 说明:

1. @property相当于对age方法进行了一个装饰,它使得我们能通过对象.方法名来调用对应的属性

2. @property所装饰的方法名与对象 . 调用的名称要保持一致

3. @property会生成另外的装饰器,@方法名.setter, @方法名.getter, @方法名.deleter,分别对应set, get, del方法。这里get方法用得很少,因为已经通过@property直接对应到了get方法 

 

 

 

转载于:https://www.cnblogs.com/yrrAwx/p/8227715.html

你可能感兴趣的文章
PostgreSQL 商用版本EPAS(阿里云ppas) 自动(postgresql.conf)参数计算与适配功能
查看>>
烂泥:学习ssh之ssh隧道应用
查看>>
Android TableLayout 常用的属性介绍及演示
查看>>
Ajax跨域访问XML数据的另一种方式——使用YQL查询语句
查看>>
[原创]让您的服务器不再有被挂马的烦恼---文件安全卫士
查看>>
流水线和PC指针
查看>>
Fiddler设置抓取https请求
查看>>
div布局小技巧
查看>>
OCP 12c最新考试原题及答案(071-4)
查看>>
MHA故障切换和在线手工切换原理
查看>>
JAVA并发,同步锁性能测试
查看>>
Python版本切换和Pip安装
查看>>
SilverLigth学习笔记--控制 Silverlight控件样式(转)
查看>>
poj3262
查看>>
第四十天笔记
查看>>
4、动态代理
查看>>
Loj #6073.「2017 山东一轮集训 Day5」距离
查看>>
我的TCP/IP学习笔记
查看>>
shell--字符串的截取变量子串串
查看>>
Cas_个人理解
查看>>