Python--10、new方法、定制属性访问、描述符和装饰器

Python–10、new方法、定制属性访问、描述符和装饰器

__ new __方法

1、__ new __ 方法相当于开辟内存,之后要传回父类。固定写法return,相当于宣告已经写好了。

2、实例是通过类里面的 __ new __方法创建出来的。

3、先调用 __ new __ 方法创建出实例,再使用__ init __ 方法初始化实例。

4、__ new __ 方法,后面括号里面的 c l s 代表的是类本身。

5、__ new __ 方法是在类 创建实例的时候自动调用的。

6、作用:当继承一些不可变的class时(例如int,str,tuple),提供一个自定义化这些类实例化过程的途径。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BXNOPPwz-1578213414426)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104170654739.png)]

#将输入的字母变为大写

class Caps(str):
    def __new__(cls, string):
        string = string.upper()
        return super().__new__(cls, string)  # 返回给父类的 __init__方法

    '''
     def __init__(self,string):
         super().__init__()
         string = string.upper()
      #这里由于str类型不可变,所以修改不会成功    
    '''


b = Caps('i love china')

'''
写入的时候:'i love china'
str的new方法:'i love china'
重写的new方法:I LOVE CHINA
赋值:  b  = ' I LOVE CHINA '

'''
print(b)

#使输入的数字一直是正数
class A(int):
    def __new__(cls, value):
        return super().__new__(cls,abs(value))

i =A (-5)
print(i)

6、单线模式:

​ 可以使用 __ new __ 方法控制只能创建一个实例。

class Earth:    #游戏、论坛、聊天、APP等
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'instance'):    #instance  是指是否有实例
        #hasattr(类名,属性名)查看某个类中是否存在指定的属性,有则返回True
        #没有实例化对象的话就可以进行一次实例化创建
            cls.instance = super().__new__(cls)
            return cls.instance

    def __init__(self):
        self.name = '任太帅'

a = Earth()   #a 进行第一次实例化
print(a.name)    #第一次实例化成功

b = Earth()
print(b.name)   #第二次实例化失败

定制属性访问

1、

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cOft3LnS-1578213414426)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104183613193.png)]

2、查:

​ hasattr(re,‘length’) #返回布尔值,查看指定类(实例)中有没有指定属性,有则返回True,没有则返回False。

​ getattr(re,‘length’) #返回属性值,查看指定类中属性的值

​ re. __ getattribute __ (‘length’) #返回属性值

​ 改:

​ setattr(re,‘length’,6) #(修改的类名,属性名,新属性值)

​ re.__ setattr __(‘length’,5)

​ 增:

​ re.aaa = 1

​ setattr(re,‘bbb’,2) #有bbb属性就该,没有就增

​ re.__ setattr __(‘ccc’,3) #同上

​ 删:

​ delattr(re,‘ccc’)

​ re.__ delattr __(‘bbb’)

​ del re

class Test:
    def __init__(self):
        self.name = '任太帅'
        self.age = '20'
        self.sex = '男'



test1 = Test()
print(test1)
# <__main__.Test object at 0x7fb80b2c4f60>
#定制属性的访问   增删改查
#查找

print(hasattr(test1,'sex'))    #查看指定类中有没有指定属性
print(getattr(test1,'name'))    #查看指定类中属性的值
#+()print
# print(test1.__getattribute__('name'))        #找到指定属性的值,没有则会报错

#修改

setattr(test1,'name','烟雨平生')    #(修改的类名,属性名,新属性值)
test1.__setattr__('name','vn')

#增加 place

test1.place = '唐朝'
setattr(test1,'qq','654665456')

#删除

delattr(test1,'namme')
test1. __delattr__('qq')
del test1   #删除实例对象

3、可以对其中的方法进行重写,例如,你不希望getattr再没找到属性时报错,因为一旦报错,程序就会停止。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0gHNT3Uv-1578213414427)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104190549893.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eIg0b7dv-1578213414427)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104190834028.png)]

描述符

描述符协议:Python 描述符是一个“绑定行为”的对象属性,在描述符协议中,,它可以通过方法重写属性的访问,这些方法有__ get __ (), __ set __ (), __ delte __().如果这些方法中的任何一个呗定义在一个对象中,这个对象就是一个描述符。

class M:
    def __get__(self, instance, owner):
        return"恭喜你升级啦!"

    def __set__(self, instance, value):
        print("你当前的攻击力为%s"%value)

    def __delete__(self, instance):
        print("你已阵亡")

class con():
    attr = M()

a = con()
print(a.attr)           #获取属性
a.attr = 100            #自己定义,set加包装
del a.attr              #删除时自动调用   delete

装饰器

闭包实现装饰器

1、直接更改函数,参数值可能会受到影响。于是在不改变原有函数的情况下,在函数外面加一个壳子,此为装饰器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9WLIDbGi-1578213414427)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104205558574.png)]

2、在函数前面加 @函数名 ,就相当于直接加了装饰器。

​ @ … 相当于给下面的函数加了一个装饰器。

​ 关键在于外部函数要返回内部函数的函数体,而且函数要传入函数。


def outer(c):
    def inner():
        # print(c)    #func  接收到函数体
        c()       #调用传入的函数体
    return inner    #返回inner的函数体

@outer     #在outer函数前加了@,就相当于直接给func函数加了装饰器
def func():
    print("hello,world")

# x = outer(func)
# x()          #执行返回来的inner函数

func()

案例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TK0E9Bkj-1578213414428)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104222629476.png)]

类实现装饰器

类的内部装饰器–特殊的作用

1、priperty 使访问方法的形式等同于访问属性(把方法当属性使用)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tUIwdjPM-1578213414428)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104211454386.png)]

2、staticmethod 静态方法。

​ 和class(当前类)断绝关系 没有self传递,相当于函数,实现了独立,和当前类没有关系了。类方法里面也不能使用类属性。

3、classmethod 类方法。

​ 可以使用类属性。原则上,类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法。

​ 类方法和静态方法的区别为类方法可以使用类属性,静态方法不可以使用类方法。

4、类中的一个方法去使用另外的方法需要用 self.方法名;

​ 也可使用静态方法,直接当函数使用就行

class Rec:
    name = '这是类'
    def __init__(self,length,width):
        self.length = length
        self.width = width

    def area(self):
        func()    #静态方法
        self.test()       #类里面调用其他方法,要使用   self.方法名
        return  self.length * self.width
    def test(self):
        pass

    @property    #访问方法的形式同等于访问属性
    def areal(self):
        print("相当于属性")
        return self.length * self.width

    # 静态方法
    @staticmethod    #和class(当前类)断绝关系  没有self传递,相当于函数
    def func(a,b):
        print("静态方法",a*b)

    #类方法
    @classmethod
    def show(cls,a,b):   # cla  是类本身   传递的是当前的类
        print("这是静态方法",a*b)



n1 = Rec(40,50)
Rec.func(30,50)   #静态方法     类名.方法名
Rec.show(60,50)   #类方法       类名.方法名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qJo5LZKX-1578213414429)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200104220924978.png)]

5、类做装饰器

#类做装饰器:
#必须使用 __call__

class Test:
    def __init__(self,func):
        self.func = func
    def __call__(self, *args, **kwargs):
        print('---正在验证---')
        return self.func()          #验证完成之后调用了func 函数

@Test
def fun_test():
    print('--正在登陆---')

fun_test()

#类做装饰器:
#必须使用 __call__

class Test:
    def __init__(self,func):
        self.func = func
    def __call__(self, *args, **kwargs):
        print('---正在验证---')
        return self.func()          #验证完成之后调用了func 函数

@Test
def fun_test():
    print('--正在登陆---')

fun_test()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值