与面试官谈笑风生 | Python面向对象之访问控制
Python从设计之初就是一门面向对象的语言,面向对象思想的第一个要素就是封装。所谓封装,通俗的讲就是类中的属性和方法,分为公有和私有,公有可以被外界访问,私有不能被外界访问,这就是封装中最关键的概念——访问控制。
访问控制有三种级别:私有、受保护、公有
私有(Private):只有类自身可以访问 受保护(Protected):只有类自身和子类可以访问 公有(Public):任何类都可以访问
由于Python不像Java,有访问控制符(private / public / protected),所以Python的访问控制也是容易被应聘者忽视和搞错的。
公有(Public)
在Python的类中,默认情况下定义的属性都是公有的。
class Foo(object): bar = 123 def __init__(self, bob): self.bob = bob print(Foo.bar) # 123 foo = Foo(456) print(foo.bob) # 456
上面类Foo
中的bar
属性就是类属性,__init__
方法中定义的bob是实例属性,bar
和bob
都是公有的属性,外部可以访问,分别print类中的bar
和实例中的bob
,输出了对应的值。
受保护(Protected)
在Python中定义一个受保护的属性,只需要在其名字前加一个下划线_
,我们将Foo方法中的bob
和bar
改为_bob
和_bar
,他们就变成了受保护的属性了,代码如下:
class Foo(object): _bar = 123 def __init__(self, bob): self._bob = bob class Son(Foo): def print_bob(self): print(self._bob) @classmethod def print_bar(cls): print(cls._bar) Son.print_bar() # 123 son = Son(456) son.print_bob() # 456
定义一个类Son
继承自Foo
,由于受保护的对象只能在类的内部和子类中被访问,不能直接调用print(Son._bar)
或print(son._bob)
来输出这两个属性的值,所以定义了print_bar
和print_bob
方法,实现在子类中输出,这段代码也正常的输出了_bar
和_bob
的值。
接下来,试着反向验证一下,在类的外部,能不能访问其属性,将上面代码的输出部分修改如下:
print(Son._bar) # 123 son = Son(456) print(son._bob) # 456
(假装)惊讶的发现,竟然没有报错,也输出了正确的值。
Python中用加下划线来定义受保护变量,是一种约定的规范,而不是语言层面真的实现了访问控制,所以,我们定义的保护变量,依然可以在外部被访问到(这是个feature,不是bug)。
私有(private)
Python定义私有属性,需要在属性名前加两个下划线__
,把上面的代码修改一下,运行一下会发现下面的代码中的任何一个print都会报错的。
class Foo(object): __bar = 123 def __init__(self, bob): self.__bob = bob class Son(Foo): def print_bob(self): print(self.__bob) # Error @classmethod def print_bar(cls): print(cls.__bar) # Error print(Son.__bar) # Error son = Son(456) print(son._bob) # Error
深入一下——私有属性真的就访问不到了吗?
要了解私有属性是否真的访问不到,需要从Python是如何实现私有属性入手。CPython中,会把双下划线的属性变为_ClassName__PropertyName
的形式,用代码演示一下:
class Foo(object): __bar = 123 print(Foo._Foo__bar) # 123
运行一下可以知道,正常输出了__bar
的值,但是不推荐这样去访问私有属性,因为不同的Python解释器对于私有属性的处理不一样。
特例
使用双下划线定义私有属性,有一种特殊情况,当属性后也有两个下划线的时候,这个属性会被Python解释器当做魔术方法,从而不做私有处理。
class Foo(object): __bar__ = 123 print(Foo.__bar__) # 123
上面代码输出了123,证明Python解释器并没有把__bar__
当做私有属性。当定义私有属性时,需要注意名字最后最多只能有一个下划线。
另一个特例
假如定义的属性名就叫__
呢?不妨直接试一下:
class Foo(object): __ = 123 print(Foo.__) # 123
可以发现名字叫__
的属性也不会被认为是私有属性,名字是多个下划线的属性也不是私有属性(比如_______
)。
函数的访问控制
前面主要介绍了属性的访问控制,在Python中函数是一等公民,所谓一等公民,就是函数可以像变量一样使用,所以函数的访问控制和属性一样,一样应用上面的规则。叉车配件
与面试官谈笑风生 | Python面向对象之访问控制的更多相关文章
- 美女面试官问我Python如何优雅的创建临时文件,我的回答....
[摘要] 本故事纯属虚构,如有巧合,他们故事里的美女面试官也肯定没有我的美,请自行脑补... 小P像多数Python自学者一样,苦心钻研小半年,一朝出师投简历. 这不,一家招聘初级Python开发工程 ...
- 【我给面试官画饼】Python自动化测试面试题精讲
那今天给家分享的是一个面试主题. 就比如说我们的自动化测试,自动化如何去应对面试官,和面试官去聊一聊自动化的心得,自动化你现在去面试的时候是一个非常重要的一个关键点,所以如果你在这方面有一定的心得.那 ...
- 面试乐融集团Python开发工程师有感
这是笔者第一次面试,,乐融集团位于朝阳区朝阳公园的乐融大厦.是下午两点的笔面试,笔者是一点半到的,然后在里面等了会,开始笔试 笔试题并不是太难,就是考的比较宽,因为笔者是校招,所以笔试题出来了数据结构 ...
- 面试官:如何在Integer类型的ArrayList中同时添加String、Character、Boolean等类型的数据? | Java反射高级应用
原文链接:原文来自公众号:C you again,欢迎关注! 1.问题描述 "如何在Integer类型的ArrayList中同时添加String.Character.Boolean等 ...
- 面试官的七种武器:Java篇
起源 自己经历过的面试也不少了,互联网的.外企的,都有.总结一下这些面试的经验,发现面试官问的问题其实不外乎几个大类,玩不出太多新鲜玩意的.细细想来,面试官拥有以下七种武器.恰似古龙先生笔下的武侠世界 ...
- python 面向对象、特殊方法与多范式、对象的属性及与其他语言的差异
1.python 面向对象 文章内容摘自:http://www.cnblogs.com/vamei/archive/2012/06/02/2532018.html 1.__init__() 创建对 ...
- 以技术面试官的经验分享毕业生和初级程序员通过面试的技巧(Java后端方向)
本来想分享毕业生和初级程序员如何进大公司的经验,但后来一想,人各有志,有程序员或许想进成长型或创业型公司或其它类型的公司,所以就干脆来分享些提升技能和通过面试的技巧,技巧我讲,公司你选,两厢便利. 毕 ...
- 浅谈面试中的OOD面向对象设计问题
转载自:http://baozitraining.org/blog/Object-oriented-design-question/ OO设计问题是电面或者onsite中常考的问题,尤其对以Java为 ...
- 前端面试回顾---javascript的面向对象
转:https://segmentfault.com/a/1190000011061136 前言 前一阵面试,过程中发现问到一些很基础的问题时候,自己并不能很流畅的回答出来.或者遇到一些基础知识的应用 ...
随机推荐
- 1.高并发教程-基础篇-之nginx负载均衡的搭建
温馨提示:请不要盲目的进行横向扩展,优先考虑对单台服务器的性能优化,只有单台服务器的性能达到最优化之后,集群才会被最大的发挥作用. 一.架构图: 服务器准备:3台,ubuntu16.04系统maste ...
- css 中的 initial inherit unset 意思
写css时,在对属性进行选值,经常遇到unset , initial,inherit三个值.这几个值的含义. 1.inherit 可继承性 继承的意思. 每一个 CSS 属性都有一个特性就是,这个属性 ...
- 【postgresql的使用】
#安装: #初始化: #允许远程登录: #创建数据库并指定用户 #创建用户 #列出数据库 #进入数据库 #查询数据 #or(或)查询 #and ,or(和,或查询) #表连接 #内,外(左右),交叉连 ...
- 基于 HTML5 Canvas 的 3D 渲染引擎构建机架式服务器
前言 今天找到了 HT 的官网里的 Demo 网站( http://www.hightopo.com/demos/index.html ),看的我眼花缭乱,目不暇接. 而且 HT 的用户手册,将例子和 ...
- 学习html的第一天
HTML 第一章: webde 运行环境: 1. 什么是HTML HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言:HyperText Markup Languge 超文本 就是网 ...
- Java实例 Part5:面向对象入门
目录 Part5:面向对象入门 Example01:成员变量的初始化值 Example02:单例模式的应用 -----懒汉式 -----饿汉式 Example03:汉诺塔问题的求解 Example04 ...
- WOT干货大放送:大数据架构发展趋势及探索实践分享
WOT大数据处理技术分会场,PingCAP CTO黄东旭.易观智库CTO郭炜.Mob开发者服务平台技术副总监林荣波.宜信技术研发中心高级架构师王东及商助科技(99Click)顾问总监郑泉五位讲师, ...
- 爬虫 Scrapy框架 爬取图虫图片并下载
items.py,根据需求确定自己的数据要求 # -*- coding: utf-8 -*- # Define here the models for your scraped items # # S ...
- # 20155224 2016-2017-2 《Java程序设计》第10周学习总结
20155224 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 密码学: 主要是研究保密通信和信息保密的学科, 包括信息保密传输和信息加密存储等. 密码学 ...
- 20155226-虚拟机与Linux之初体验
虚拟机与Linux之初体验 虚拟机的安装 虚拟机对我来说不是很了解,但今天在安装过程中加深了我的理解.虚拟机是一个在原来系统基础上进行的又一个系统安装,可以在不影响前者的情况下完成一些其不能解决的问题 ...