2019/11/10 05-访问控制-猴子补丁-属性装饰器-对象销毁

本文探讨Python中私有属性的实现方式,包括单下划线和双下划线的使用,以及它们对属性访问的影响。同时介绍了如何利用属性装饰器实现更安全的数据访问,并讨论了封装的概念和好处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述在这里插入图片描述在这里插入图片描述
能通过一个函数来约束对内部属性的调整,让它在一个合理的范围之内
python的私有属性,私有跟个体有关,
python中别人能通过访问属性,能够破坏对属性的控制,所以写了跟没写一样

在这里插入图片描述
在属性前面加两个__下划线,就访问不到了在这里插入图片描述
如何拿到这个age在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
动态增加了一个属性,就是实例的属性在这里插入图片描述
只不过是把你想要的age改名字,class。__age
编译器修改这个,就会在字典里增加__person__在这里插入图片描述
这样就可以使用了
在这里插入图片描述
碰到下划线开头,你就不必要修改了,但是最好还是不修改 了

双下划线__就是私有属性,还是放在字典中的(就是改个名,知道改个名依然可以访问),只要在定义范围内,出现双下划线的属性,实例的属性,都会替你改名*在这里插入图片描述
加一个下划线
在这里插入图片描述
注释掉在这里插入图片描述
添加一个getname
在这里插入图片描述

使用一个_下划线开头的叫保护变量
在这里插入图片描述
打印一下字典
在这里插入图片描述
** __双下划线是私有,不是随便暴露给你的,在类的外部使用双下划线,是不允许的
在类的外面使用单下划线,_,比如_name,其实是一个保护变量(不希望进行改动和访问)**
在这里插入图片描述
保护变量不会改名(dict里的名字),保护变量是大家自己封的,本来是没有这个名字,
这个是python约定俗成,这是python代码的作者告诉你,不要乱动(但是其实根本挡不住,想用就用)
下划线只是一种警告,告诉你是私有保护成员,只能内部使用,不推荐你使用,你用了后果自付,、
__双下划线,私有这个属性会被改名,单下划线_是编程者约定的,不会改任何名称
在这里插入图片描述
其实_name和heght没什么区别,只不过下划线告诉你不要随便使用
在这里插入图片描述
现在看到的是属性,方法是否可以
看一下类属性

在这里插入图片描述在这里插入图片描述
** _x=200,名字没有修改**
在这里插入图片描述
双下划线就改名了
在这里插入图片描述
但下划线就是可以直接访问的,但是i__双下划线就不行,名字都不一样了
在这里插入图片描述
这样写,400,500都改了

在这里插入图片描述
这样做就把内部的一些属性改掉,不管你是类属性还是实例

现在在_getage,__getname前面加下划线
在这里插入图片描述
getage,__getname都改变了在这里插入图片描述
只要是在类里面定义的这个属性或者方法的名称,不管是类属性还是方法的名称,或者实例的属性,只要出现了双下划线,解释器都要给你修改名称,就造成一种你访问不到的假象,如果把字典__dict__打开了,看到了名称就想怎么访问就怎么访问
在这里插入图片描述
其实这个写了跟没写一样,因为使用python的人都是程序员,看两眼就知道了

通常这种方式就可以访问了
在这里插入图片描述在这里插入图片描述在这里插入图片描述
看字典就都什么都看到了
在这里插入图片描述
私有变量的本质:
类定义的时候,如果声明一个实例变量的时候,使用双下划线,python解释器会将其改名,转换名称为_变量名的名称,所以用原来的名字访问不到了

在这里插入图片描述
知道名称就可以访问了
在这里插入图片描述
类内的访问都受到改名的影响
在这里插入图片描述
类外不受改名影响,相当于重新定义一个带双下划线__,在类外面不会替它改名
在这里插入图片描述

在这里插入图片描述
保护变量加一个下划线即可,根本什么都没做,只不过告诉你不要跟普通属性直接取操作,因为这是开发者约定俗成的
在这里插入图片描述在这里插入图片描述
** _单下划线什么都不做(编程者约定,__双下划线已经改名了,解释器会帮你做改名的工作**
在这里插入图片描述
改名仅限在类定义的内部实现,超出类的范围改名是没有用的
在这里插入图片描述
私有方法也是改个名(类属性也是同样原则)
类属性,方法,还有实例的属性都是一样的,只要使用__双下划线就全部改名
在这里插入图片描述在这里插入图片描述
对于我们来讲,不管是私有的属性,还是私有的方法,都喜欢称为私有成员,都是member,公有的方法,和公有的属性,称为公有的成员,保护的属性和方法称为保护成员,是属性和方法,和起来叫成员
不管是什么访问控制都不能在python中阻止用户修改类的成员,python中没有绝对安全的成员

单下划线_,只是警告和提醒,请你遵守约定,不清楚不要使用

在运行时,对属性,方法,函数等进行动态替换,叫猴子补丁
其目的往往是为了通过替换,修改来增强,扩展原有代码的能力。
黑魔法,慎用
(就是原来程序有bug,打个补丁就动态修复掉

在这里插入图片描述

定义类person,定义方法get_score,在t1中定义
在这里插入图片描述
从t1中导入这个类
在这里插入图片描述
在t2中定义方法,这个就是未来补丁在这里插入图片描述
使用猴子补丁
在这里插入图片描述
类似于把一个函数对象送给了一个函数在这里插入图片描述
用实例来调用方法,要第一参数self
在这里插入图片描述在这里插入图片描述
要传一个person进去在这里插入图片描述
在运行之前就把补丁补上
赋值即重新定义
运行时动态去修改一个类
在这里插入图片描述
甚至都可以这么做
在这里插入图片描述
完全可以偷梁换柱,你想改什么就什么
在这里插入图片描述
只要认识标识符,一切都是变量,可以动态修改所有属性,类属性还是实例属性,你想修改什么就修改什么、
在运行模块中修改打补丁
在这里插入图片描述

属性装饰器

在这里插入图片描述在这里插入图片描述如果是私有成员和保护成员,类似提供getage这样的方法来进行访问,python为了提供方便,用了一个属性装饰器。,以后写面向对象,只要提供属性就是property
在这里插入图片描述
加了property,下面的名字最好改成未来的属性名

在这里插入图片描述
加一个属性装饰器,就不需要带括号进行访问了
在这里插入图片描述
执行一下在这里插入图片描述
不能这么直接修改值,不允许设置属性
在这里插入图片描述
要修改还有一个设置装饰器,property称为获取装饰器,getter,
设置值要从外面塞入一个参数进来,所以要一个self和value

在这里插入图片描述
点击property在这里插入图片描述
例子已经在这里了,setter要给一个值才能设置进去在这里插入图片描述
delteter时删除的时候用的,同名age.deleter在这里插入图片描述
在下面的时候使用,非常少使用在这里插入图片描述

python不允许直接setter,要求必须有一个getter,有了getter,setter还是deleter随你
在这里插入图片描述
不用装饰器是否可以
在这里插入图片描述
这个就代表动态增加1个属性
在这里插入图片描述
这样就是定义了一个属性,这个属性叫age,设置了第一个参数,是用来getter的
,这样就只有getter没有setter,就报错了
在这里插入图片描述
下面写成这样,有getter才能有setter
在这里插入图片描述
因为property是class,本质上是个类,拿一个类作为装饰器
在这里插入图片描述
这个类需要几个参数,查看init初始方法,送get,set,del,参数,最后送文档字符doc在这里插入图片描述
用这种方法就可以定义getter和setter,getter和setter放到函数里即可
现在不这么做,

这么一定会报错,因为只定义了getter
在这里插入图片描述
setter用lambda表达式写不出来,写等号会抛出异常
在这里插入图片描述
大多数情况都用这一种在这里插入图片描述
看看这个装饰器的等价式
age.setter相当于给上面的送第二参数

在这里插入图片描述
尤其是功能类都会有属性装饰器的
在这里插入图片描述
setter和deleter必须在getter后面在这里插入图片描述在这里插入图片描述
其他写法就是property这种方式在这里插入图片描述
lambda方式就没发写setter,赋值语句不能这么写

对象如何销毁

在这里插入图片描述
实例化是new,初始化是init
在这里插入图片描述
定义一个tom之后最后被删除了
在这里插入图片描述
可以直接用实例调用在这里插入图片描述
等号上面是自己做的,下面是垃圾回收做的在这里插入图片描述等号上面是自己做的,下面是垃圾回收做的
在这里插入图片描述
三个变量都指向同一个内存空间
del如果立即消亡,会看到del打印出来,等三秒之后,说明三秒之后才消亡的的
三秒之后才打印出来的

在这里插入图片描述
tom,tom1,tom3,代表这个对象最少被引用三次,del tom,只能说明引用计数-1

再删除一个tom1,会不会触发del,不会,程序消亡所有变量都需要消亡,tom2也要消亡
在这里插入图片描述
把tom2删除,触发了就有了

因为这里已经引用计数为0了,但是什么时候清楚,是垃圾回收说了算,是保不齐的时候
在这里插入图片描述
在程序执行完,引用计数为0,为主动调用一次垃圾回收,,没必要手动调用,在消亡的时候回再调用一次,del这个方法是消亡的时候是实例消亡的时候调用的。
前面调用多少次,都没用

在这里插入图片描述
这是函数不是删除对象本身的,这个是垃圾回收的事情,这里面实际上是清理工作,比如打开了很多文件描述符,最后要把这些文件描述符closs掉,但是对象的消亡不是在这里做的
比如下面的open
在这里插入图片描述
**类中可以定义析构函数,del
作用:销毁类的实例的时候调用,以释放占用的资源。其中就放些清理资源的代码,比如释放连接(文件描述符)。
注意这个方法不能引起对象的真正销毁,只是对象销毁的时候会自动调用它。
使用del语句删除实例,引用计数减1。当引用计数为0时,会自动调用del_ 方法。
由于Python实现了垃圾回收机制,不能确定对象何时执行垃圾回收。
**在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在内存回收的时候,会在回收前自动调用这个delete方法,确保你能把占用资源释放掉,然后由垃圾回收把对象清理掉

在这里插入图片描述
其他的语言一般这么写
所谓重载,就是同一个方法名,但是参数数量,类型不一样,就是同一个方法的重载,参数类型不同,返回值不同,下面两套就属于重载了

在这里插入图片描述
python用一个就可以搞定了,天然重载在这里插入图片描述
有时候可能有这样的版本,这也叫重载,参数的个数也不一样
在这里插入图片描述
但是在python中写成这样就不能重载了
在这里插入图片描述
python的传参不需要指定类型,参数注解只是一个说明而非约束性的,多个参数可以用可变参数
不需要重载就能完成别的语言中重载的功能

在这里插入图片描述
**学完这些理解下封装,Encapsulation
可以把一些属性隐藏起来,不能让你直接调用
能过访问控制,暴露出适当的熟悉和数据,操作提供给用户,该隐藏的隐藏起来,该保护的保护起来
**

在这里插入图片描述
封装的好处就是做数据的隐藏,把该隐藏的一定要隐藏,这种叫访问控制,如果真的要访问就可以用属性装饰器,getter,setter
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值