Python面向对象-访问限制
在Class内部,可以有字段,方法和属性,而外部代码可以通过直接调用实例变量的方法来操作数据,
(1)私有普通字段
比如对于下面的Student类,name字段可以在外面通过对象进行直接访问:
class Student(object):
def __init__(self, name):
self.name = name def get_name(self):
return self.name rob = Student("Rob")
rob.name = 'Rob1'
print(rob.get_name())
上面的程序输出是 Rob1
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__
,在Python中,实例的变量名如果以__
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改:
class Student(object):
def __init__(self, name):
self.__name = name def get_name(self):
return self.__name rob = Student("Rob")
rob.__name = 'Rob1'
print(rob.get_name())
改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name,我们看到程序输出是 Rob ,也就是代码 rob.__name = 'Rob1' 并不生效。
这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。
但是如果外部代码要修改name怎么办?可以给Student类增加set_name
这样的方法:
class Student(object):
... def set_name(self, name):
self.__name = name
你也许会问,原先那种直接通过rob.name= "Rob1"
也可以修改啊,为什么要定义一个方法大费周折?因为在方法中,可以对参数做检查,避免传入无效的参数,比如我们想对学生类的score操作:
class Student(object):
... def get_score(self):
return self.__score def set_score(self, value):
if 0 <= value <= 100:
self.__score = value
else:
raise ValueError("Bad score")
需要注意的是,在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。
有些时候,你会看到以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量
但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。
总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。
还有一个问题需要注意,
假如有子类继承了Student类,那么private字段能否在子类中访问呢?我们来看下面的例子,Freashman类继承Student类,在Freashman类中尝试获取__score属性:
class Student(object):
def __init__(self, name):
self.__name = name
self.__score = 0 def get_name(self):
return self.__name def set_name(self, name):
self.__name = name def get_score(self):
return self.__score def set_score(self, value):
if 0 <= value <= 100:
self.__score = value
else:
raise ValueError("Bad score") class Freshman(Student):
def get_score(self):
return self.__score mary = Freshman("Mary")
print(mary.get_score())
运行程序将报错: AttributeError: 'Freshman' object has no attribute '_Freshman__score'
因此私有成员除了类本身内部,其他地方都不可访问。
(2)私有静态字段
我们知道类除了有普通字段,还有静态字段,对于静态字段我们也可以限制只在类内部访问,只是和普通字段稍有不同:
(1)静态字段通过类访问
(2)可以将内部访问的方法设置为静态方法:
class Student(object):
__nationality = 'China' ... @staticmethod # 静态方法
def get_nationality():
return Student.__nationality # 通过类访问 @staticmethod # 静态方法
def set_nationality(nation):
Student.__nationality = nation # 通过类访问 print(Student.get_nationality())
Student.set_nationality('USA')
print(Student.get_nationality())
方法、属性的访问于上述方式相似,即:私有成员只能在类内部使用
Python面向对象-访问限制的更多相关文章
- Python面向对象-访问权限public和private
上一节我们介绍了,Class内部可以有属性和方法,外部代码通过直接调用实例的方法来操作数据,这样就可以隐藏内部的逻辑实现:同时,外部代码还是可以自由的修改实例的属性和增加方法. 但是有时候,我们不想这 ...
- Python 面向对象编程——访问限制
<无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...
- python面向对象进阶(八)
上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- python 面向对象(进阶篇)
上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- python 面向对象学习
------Python面向对象初 下面写一个类的简单实用,以便方便理解类 #python 3.5环境,解释器在linux需要改变 #阅读手册查询readme文件 #作者:S12-陈金彭 class ...
- python面向对象(二)——类成员
Python面向对象 类成员 1.字段 普通字段 属于对象 静态字段 属于类 2.方法 普通方法 触发者是对象 括号里至少一个参数 se ...
- Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)
Python开发[第七篇]:面向对象 详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇) 上一篇<Python 面向对象(初级篇)> ...
- [Python学习笔记][第六章Python面向对象程序设计]
1月29日学习内容 Python面向对象程序设计 类的定义与使用 类定义语法 使用class关键词 class Car: def infor(self): print("This is ca ...
随机推荐
- mybatis使用*号查询数据丢失问题
使用*号的SQL语句:select * from 表名 在开发过程中可能你会发现使用mybatis框架爱作为持久层时,写的SQL语句在工具里面查询数据是可以查到想要的数据的,但是在项目中会出现数据丢失 ...
- Jquery中复选框选中取消实现文本框的显示隐藏
标签内容 <div class="box"> 请编写javascript代码,完成如下功能要求:<br /> 1.取消复选款后,要求促销价格.促销开始结束日 ...
- mongodb C++ Driver安装
前言 mongocxx官网地址 http://mongocxx.org/?jmp=docs 本文的安装版本是:mongocxx-r3.2.0.tar.gz . 参考文档安装过程http://mongo ...
- Spring Boot 多环境部署
再简单的应用系统,通常都有两个环境——开发环境和线上环境.大型的企业应用还会有更多的环境,比如测试环境.准线上环境.演示环境等.应用的版本也可能对应了多个环境,比如1.0版本的演示环境.2.0版本的演 ...
- Java : logback简单配置
需要把logback.xml文件放在类路径下,如果是spring boot项目可以用 logging.config=classpath:log/xxxxxx.xml来指定配置文件 logback la ...
- PHP对接QQ互联,超级详细!!!
SDK下载
- 大数据学习--day11(抽象类、接口、equals、compareTo)
抽象类.接口.equals.compareTo 什么是抽象方法 ? 区分于正常的方法 1.使用了 abstract 修饰符 该修饰符修饰方法 则该方法就是抽象方 ...
- Java设计模式(20)——行为模式之命令模式(Command)
一.概述 概念 类似C中的callback! UML简图 角色 客户端:创建具体命令,指定接收者 命令接口:声明命令的接口 具体命令:定义接收者和行为之间的弱耦合(execute执行方法) 请求者(I ...
- 浅谈Hash在多个字符串匹配类型问题中的应用
在生活中们有时会遇到一些有关字符串匹配的问题. 这时打暴力往往显得很愚蠢,效率低下. 所以就需要一些算法和数据结构来提高效率. Hash Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把 ...
- 南京Uber优步司机奖励政策(12月14日到12月20日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...