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 ...
随机推荐
- CSS之元素
CSSS书写位置 内嵌式 <head> <style type = "text/css"> **** </style> </head> ...
- 开发类似"音速启动"的原创工具简码"万能助手"的过程中对ztree.js与win标准控件treeview、HTMLayout树形框等优缺点的比较
在开发类似"音速启动"的桌面快捷方式管理软件简码"万能助手"的早期规划中,曾经考虑过几种树形框方案: ztree.js.win标准控件treeview.HTML ...
- win10 pro 永久激活
win10 专业版永久激活 转自雨林木风 查看激活状态 ·"Windows+R"打开"运行"窗口,输入"slmgr.vbs -xpr"并点击 ...
- 走进MySQL
MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用 ...
- 跨浏览器实现placeholder效果的jQuery插件
曾经遇到这样一个问题,处理IE8密码框placeholder属性兼容性.几经周折,这个方案是可以解决问题的. 1.jsp页面引入js插件 <script type="text/java ...
- 对DataSet,DataRow,DateTable转换成相应的模型
/// <summary> /// DataRow 转成 模型 /// </summary> /// <t ...
- Python系列之入门篇——pytables及其客户端
pytables及其客户端查看 pytables # ubuntu sudo apt-get install python-tables pip install flask flask-httpaut ...
- Div标签使用inline-block有间距
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- PWA-缓存
PWA-缓存 基础 PWA强大的离线能力就在于Service Worker拦截请求及提供缓存的能力,Service Worker的缓存能力比较强大,它能够赋予你更加精确控制缓存的能力.示例页面 < ...
- 22-Consent 确认逻辑实现
1-定义一个从前台传到后台的viewModel namespace MvcCookieAuthSample.Models { public class InputConsentViewModel { ...