与面试官谈笑风生 | Python面向对象之访问控制

Python封装详解
本文详细介绍了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是实例属性,barbob都是公有的属性,外部可以访问,分别print类中的bar和实例中的bob,输出了对应的值。

受保护(Protected)

在Python中定义一个受保护的属性,只需要在其名字前加一个下划线_,我们将Foo方法中的bobbar改为_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_barprint_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中函数是一等公民,所谓一等公民,就是函数可以像变量一样使用,所以函数的访问控制和属性一样,一样应用上面的规则。叉车配件

转载于:https://www.cnblogs.com/xyou/p/8854761.html

### 按键控制流水灯的接线方式及原理 #### 接线方式 在按键控制LED流水灯实验中,为了实现按键切换LED灯循环闪烁的方向,需要合理设计电路布局。具体来说: - **电源接地**:确保所有元件共用同一电源和地线连接[^1]。 - **LED灯限流电阻**:每个LED灯应串联一个至少220Ω的电阻以保护其不被过高电流损坏[^2]。 - **按键开关**:按键的一端接到微控制器输入引脚上,另一端通常拉低至GND或者通过内部/外部上拉机制保持高电平状态,在按下时改变逻辑信号。 以下是基于Arduino平台的一个典型实例说明: ```plaintext +5V ----|>|---- R (>=220Ω) ---- Pin 8 LED D1 |>|---- R (>=220Ω) ---- Pin 9 LED D2 |>|---- R (>=220Ω) ---- Pin 10 LED D3 |>|---- R (>=220Ω) ---- Pin 11 LED D4 GND Pin X ---- Button Switch ---- GND Direction Control Key ``` 其中,“Button Switch”代表用于更改流动方向的按钮;而“Pin X”表示实际使用的GPIO编号,需依据程序设定调整。 对于更复杂的多路或多向操作场景,则可能引入多个独立按键分别负责不同功能触发,比如前进、后退甚至暂停等功能选项[^3]。 #### 工作原理 整个系统的运作依赖于软件编程配合硬件配置共同完成。当某个特定位置上的按键被按压之后,会产生相应的电信号变化传送到单片机相应IO口中去检测识别出来并作出反应动作——即按照预设算法重新排列点亮序列从而达到视觉效果转换的目的。 例如上述提到过的C语言项目里运用到了中断技术手段来提升响应速度以及精确度方面表现优异之处就在于此。每当有新的事件发生如按键闭合断开等情况都会引发一次进入服务子程序过程期间执行专门处理任务直至结束返回继续原来正常流程运行下去直到再次遇到下一个干扰因素为止形成闭环控制系统结构特征明显区别其他简单轮询扫描方法相比效率更高稳定性更强适应范围也更加广泛适用场合众多深受开发者喜爱推崇不已成为现代电子制作领域不可或缺重要组成部分之一值得深入研究学习掌握应用技巧提高技术水平创造更大价值回报社会贡献力量造福人类文明进步事业添砖加瓦共同努力奋斗前行不断超越自我追求卓越成就梦想未来无限美好充满希望曙光就在前方等待我们勇敢迈向新征程开启新纪元谱写新篇章铸就辉煌业绩载入史册永垂青史万古流传千秋颂扬百世敬仰十方赞叹九天揽月八荒驰骋七彩斑斓六艺精通五湖四海四通八达三山五岳二龙戏珠一箭双雕零失误百分百成功几率百分之二百努力程度十分满意结果圆满达成共识团结协作精神风貌昂扬向上斗志旺盛所向披靡无坚不摧势不可挡锐意进取开拓创新时俱进日新月异蒸蒸日上年年红火岁岁平安幸福安康吉祥如意万事胜意心想事成梦寐以求功成名遂志得意满人生赢家笑傲江湖纵横捭阖谈笑风生挥洒自如游刃有余炉火纯青登峰造极臻于化境超凡脱俗遗世独立鹤立鸡群脱颖而出独占鳌头拔得头筹名列前茅首屈一指举重若轻驾轻就熟熟能生巧水到渠成瓜熟蒂落顺理成章自然而然恰逢其会适得其所各取所需互利共赢共享成果共创辉煌明天!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值