Python包装与授权

包装在Python中经常用到,包装就是把已存在的程序重新打包,使这个程序更加适合当前应用环境。而授权是包装特有的一个属性,通过授权,可以使当前类调用传入对象已存在的属性。

1. 包装

包装就是对已存在对象的属性功能进行调整,删除不需要的、添加或是修改已存在的功能,以达到自己所理想的规格,并装换成另外一种更适合当前使用场合的对外接口。包装包括定义一个类,它的实例拥有标准类型的核心行为。

例如,我们需要处理一个数据,处理这个数据需要一系列的步骤,我们可以将这些步骤写到一个类里面。每当应用于不同的场景时,就将各种适合于此场景的方法包装成类,且原对象的属性和方法依然可以调用。

或许我们会觉得通过继承的方式可以达到这个目的,将父类中的成员全部继承,然后再对方法进行覆盖重写,还可以添加自己想要的属性和方法。但是在 Python2.2之前,基本数据类型不属于类,这样基本数据类型就不能被继承,也不能进行包装。

以下是包装实例:

class Wrap(object):  
    def __init__(self,obj):     # 声明了构造函数,模拟要包装对象的构造方法  
        self.__obj = obj     # __obj就是这个被包装对象的核心  
    def get(self):     # 获取__obj对象  
        return self.__obj  
    def __repr__(self):  
        return 'self.__obj'  
    def __str__(self):     # 转换__obj对象  
        return str(self.__obj)  
    def __getattr__(self,thelist):  
        return getattr(self.__obj,thelist)  

2. 授权

授权是包装的一个特性,采用已存在的功能达到最大限度的代码重用。在包装中我们可以新建、修改或删除已有的功能,授权的过程就是将更新的功能交由新类来处理,已存在的功能就授权给对象的默认属性

要实现授权,一定要覆盖__getattr__()方法。在代码里包含一个对getattr()内建函数的调用,**调用getattr()**得到默认对象的属性(数据属性或者方法)并返回它,以便于访问或者调用。

当引用一个属性时,解释器首先会在局部名称空间中查找那个名字,比如一个自定义的方法或局部实例属性。如果没有在局部字典中找到,则搜索类名称空间,以防一个类属性被访问。最后,如果两类搜索都失败了,搜索则对原对象开始授权请求,此时__getattr__()会被调用。

对象销毁也称垃圾回收,很多语言都有自己的垃圾回收机制。Python 的垃圾回收机制使用了引用计数这一机制来追踪内存中的对象。

3. 增加引用计数

在 Python 中,当一个对象被创建时,就自动地创建了一个引用计数器。当引用计数加1时,增加对这个对象的引用,引用计数器也依次增加。

例如:

x = 12  
y = x  
z = y  

在这个例子中,语句x = 12创建了对象12并将这个对象赋值给了x。此时12的引用计数为1,语句y = x创建了一个指向对象12的别名y,计数为2,在语句z = y中又创建了一个别名,所以此时对象12的引用计数为3。

对象的引用计数在下列情况下增加:

  • 对象被创建时;
  • 创建了另一个别名时;
  • 被作为参数传递给函数时;
  • 成为容器对象的一个元素时。

4. 减少引用计数

当别名被重新赋值时,源对象的引用计数减1。

例如:

var1 = "we"  
var2 = var1  
var1 = 12  

在这个例子中,对象"we"赋值给了var1,引用为1,语句var2 = var1将对象的值又赋给了var2,引用为2。但在语句var1 = 12中,将对象12赋值给了var1,此时对象"we"的引用减1,12的引用加1。

对象的引用计数在下列情况下减少:

  • 一个本地引用离开了其作用范围时,比如函数结束;
  • 对象别名被销毁时;
  • 对象本身被销毁时。

5. 对象销毁

当对象的引用计数变为0时,它被垃圾回收。Python 中的垃圾回收机制可以处理两种情况,一种是引用为0另一种是循环引用。循环引用是指两个对象互相引用,且都没有外部的对象对它们进行引用

例如:

class delObject:  
    def __init__(self):  
        self.var = 100  
    def __del__(self):  
        class_name = self.__class__.__name__  
        print("对象%s销毁" %class_name)  
do1 = delObject()  
do2 = do1  
do3 = do1  
print(id(do1))  
print(id(do2))  
print(id(do3))  
del(do1)  
del(do2)  
del(do3)  

结果为:

2176419869752  
2176419869752  
2176419869752  
对象delObject销毁  

在这个例子中,del()为一个析构函数。当删除对象时,会调用本身的函数,在对象删除完毕时也会再次调用这个函数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小廖同志_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值