zoukankan      html  css  js  c++  java
  • python描述符

    转载地址:http://www.cnblogs.com/linhaifeng/articles/6204014.html#_label6

    描述符(__get__,__set__,__delete__)

    1 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议
    __get__():调用一个属性时,触发
    __set__():为一个属性赋值时,触发
    __delete__():采用del删除属性时,触发

    1 class Foo: #在python3中Foo是新式类,它实现了三种方法,这个类就被称作一个描述符
    2     def __get__(self, instance, owner):
    3         pass
    4     def __set__(self, instance, value):
    5         pass
    6     def __delete__(self, instance):
    7         pass

    2 描述符是干什么的:描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)

     1 class Foo:
     2     def __get__(self, instance, owner):
     3         print('触发get')
     4     def __set__(self, instance, value):
     5         print('触发set')
     6     def __delete__(self, instance):
     7         print('触发delete')
     8 
     9 #包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法
    10 f1=Foo()
    11 f1.name='egon'
    12 f1.name
    13 del f1.name
    14 #疑问:何时,何地,会触发这三个方法的执行
    15 
    16 引子:描述符类产生的实例进行属性操作并不会触发三个方法的执行
     1 #描述符Str
     2 class Str:
     3     def __get__(self, instance, owner):
     4         print('Str调用')
     5     def __set__(self, instance, value):
     6         print('Str设置...')
     7     def __delete__(self, instance):
     8         print('Str删除...')
     9 
    10 #描述符Int
    11 class Int:
    12     def __get__(self, instance, owner):
    13         print('Int调用')
    14     def __set__(self, instance, value):
    15         print('Int设置...')
    16     def __delete__(self, instance):
    17         print('Int删除...')
    18 
    19 class People:
    20     name=Str()
    21     age=Int()
    22     def __init__(self,name,age): #name被Str类代理,age被Int类代理,
    23         self.name=name
    24         self.age=age
    25 
    26 #何地?:定义成另外一个类的类属性
    27 
    28 #何时?:且看下列演示
    29 
    30 p1=People('alex',18)
    31 
    32 #描述符Str的使用
    33 p1.name
    34 p1.name='egon'
    35 del p1.name
    36 
    37 #描述符Int的使用
    38 p1.age
    39 p1.age=18
    40 del p1.age
    41 
    42 #我们来瞅瞅到底发生了什么
    43 print(p1.__dict__)
    44 print(People.__dict__)
    45 
    46 #补充
    47 print(type(p1) == People) #type(obj)其实是查看obj是由哪个类实例化来的
    48 print(type(p1).__dict__ == People.__dict__)
    49 
    50 描述符应用之何时?何地?

    3 描述符分两种
    一 数据描述符:至少实现了__get__()和__set__()

    1 class Foo:
    2     def __set__(self, instance, value):
    3         print('set')
    4     def __get__(self, instance, owner):
    5         print('get')

    二 非数据描述符:没有实现__set__()

    1 class Foo:
    2     def __get__(self, instance, owner):
    3         print('get')

    4 注意事项:
      一 .描述符本身应该定义成新式类,被代理的类也应该是新式类
      二 .必须把描述符定义成这个类的类属性,不能为定义到构造函数中
      三 .要严格遵循该优先级,优先级由高到底分别是
        1.类属性
        2.数据描述符
        3.实例属性
        4.非数据描述符
        5.找不到的属性触发__getattr__()

     1 #描述符Str
     2 class Str:
     3     def __get__(self, instance, owner):
     4         print('Str调用')
     5     def __set__(self, instance, value):
     6         print('Str设置...')
     7     def __delete__(self, instance):
     8         print('Str删除...')
     9 
    10 class People:
    11     name=Str()
    12     def __init__(self,name,age): #name被Str类代理,age被Int类代理,
    13         self.name=name
    14         self.age=age
    15 
    16 
    17 #基于上面的演示,我们已经知道,在一个类中定义描述符它就是一个类属性,存在于类的属性字典中,而不是实例的属性字典
    18 
    19 #那既然描述符被定义成了一个类属性,直接通过类名也一定可以调用吧,没错
    20 People.name #恩,调用类属性name,本质就是在调用描述符Str,触发了__get__()
    21 
    22 People.name='egon' #那赋值呢,我去,并没有触发__set__()
    23 del People.name #赶紧试试del,我去,也没有触发__delete__()
    24 #结论:描述符对类没有作用-------->傻逼到家的结论
    25 
    26 '''
    27 原因:描述符在使用时被定义成另外一个类的类属性,因而类属性比二次加工的描述符伪装而来的类属性有更高的优先级
    28 People.name #恩,调用类属性name,找不到就去找描述符伪装的类属性name,触发了__get__()
    29 
    30 People.name='egon' #那赋值呢,直接赋值了一个类属性,它拥有更高的优先级,相当于覆盖了描述符,肯定不会触发描述符的__set__()
    31 del People.name #同上
    32 '''
    33 
    34 类属性>数据描述符
    #描述符Str
    class Str:
        def __get__(self, instance, owner):
            print('Str调用')
        def __set__(self, instance, value):
            print('Str设置...')
        def __delete__(self, instance):
            print('Str删除...')
    
    class People:
        name=Str()
        def __init__(self,name,age): #name被Str类代理,age被Int类代理,
            self.name=name
            self.age=age
    
    
    p1=People('egon',18)
    
    #如果描述符是一个数据描述符(即有__get__又有__set__),那么p1.name的调用与赋值都是触发描述符的操作,于p1本身无关了,相当于覆盖了实例的属性
    p1.name='egonnnnnn'
    p1.name
    print(p1.__dict__)#实例的属性字典中没有name,因为name是一个数据描述符,优先级高于实例属性,查看/赋值/删除都是跟描述符有关,与实例无关了
    del p1.name
    
    数据描述符>实例属性
    class Foo:
        def func(self):
            print('我胡汉三又回来了')
    f1=Foo()
    f1.func() #调用类的方法,也可以说是调用非数据描述符
    #函数是一个非数据描述符对象(一切皆对象么)
    print(dir(Foo.func))
    print(hasattr(Foo.func,'__set__'))
    print(hasattr(Foo.func,'__get__'))
    print(hasattr(Foo.func,'__delete__'))
    #有人可能会问,描述符不都是类么,函数怎么算也应该是一个对象啊,怎么就是描述符了
    #笨蛋哥,描述符是类没问题,描述符在应用的时候不都是实例化成一个类属性么
    #函数就是一个由非描述符类实例化得到的对象
    #没错,字符串也一样
    
    
    f1.func='这是实例属性啊'
    print(f1.func)
    
    del f1.func #删掉了非数据
    f1.func()
    
    实例属性>非数据描述符
    class Foo:
        def __set__(self, instance, value):
            print('set')
        def __get__(self, instance, owner):
            print('get')
    class Room:
        name=Foo()
        def __init__(self,name,width,length):
            self.name=name
            self.width=width
            self.length=length
    
    
    #name是一个数据描述符,因为name=Foo()而Foo实现了get和set方法,因而比实例属性有更高的优先级
    #对实例的属性操作,触发的都是描述符的
    r1=Room('厕所',1,1)
    r1.name
    r1.name='厨房'
    
    
    
    class Foo:
        def __get__(self, instance, owner):
            print('get')
    class Room:
        name=Foo()
        def __init__(self,name,width,length):
            self.name=name
            self.width=width
            self.length=length
    
    
    #name是一个非数据描述符,因为name=Foo()而Foo没有实现set方法,因而比实例属性有更低的优先级
    #对实例的属性操作,触发的都是实例自己的
    r1=Room('厕所',1,1)
    r1.name
    r1.name='厨房'
    
    再次验证:实例属性>非数据描述符
    class Foo:
        def func(self):
            print('我胡汉三又回来了')
    
        def __getattr__(self, item):
            print('找不到了当然是来找我啦',item)
    f1=Foo()
    
    f1.xxxxxxxxxxx
    
    非数据描述符>找不到

    5 描述符使用

    众所周知,python是弱类型语言,即参数的赋值没有类型限制,下面我们通过描述符机制来实现类型限制功能

     1 class Str:
     2     def __init__(self,name):
     3         self.name=name
     4     def __get__(self, instance, owner):
     5         print('get--->',instance,owner)
     6         return instance.__dict__[self.name]
     7 
     8     def __set__(self, instance, value):
     9         print('set--->',instance,value)
    10         instance.__dict__[self.name]=value
    11     def __delete__(self, instance):
    12         print('delete--->',instance)
    13         instance.__dict__.pop(self.name)
    14 
    15 
    16 class People:
    17     name=Str('name')
    18     def __init__(self,name,age,salary):
    19         self.name=name
    20         self.age=age
    21         self.salary=salary
    22 
    23 p1=People('egon',18,3231.3)
    24 
    25 #调用
    26 print(p1.__dict__)
    27 p1.name
    28 
    29 #赋值
    30 print(p1.__dict__)
    31 p1.name='egonlin'
    32 print(p1.__dict__)
    33 
    34 #删除
    35 print(p1.__dict__)
    36 del p1.name
    37 print(p1.__dict__)
    38 
    39 牛刀小试
     1 class Str:
     2     def __init__(self,name):
     3         self.name=name
     4     def __get__(self, instance, owner):
     5         print('get--->',instance,owner)
     6         return instance.__dict__[self.name]
     7 
     8     def __set__(self, instance, value):
     9         print('set--->',instance,value)
    10         instance.__dict__[self.name]=value
    11     def __delete__(self, instance):
    12         print('delete--->',instance)
    13         instance.__dict__.pop(self.name)
    14 
    15 
    16 class People:
    17     name=Str('name')
    18     def __init__(self,name,age,salary):
    19         self.name=name
    20         self.age=age
    21         self.salary=salary
    22 
    23 #疑问:如果我用类名去操作属性呢
    24 People.name #报错,错误的根源在于类去操作属性时,会把None传给instance
    25 
    26 #修订__get__方法
    27 class Str:
    28     def __init__(self,name):
    29         self.name=name
    30     def __get__(self, instance, owner):
    31         print('get--->',instance,owner)
    32         if instance is None:
    33             return self
    34         return instance.__dict__[self.name]
    35 
    36     def __set__(self, instance, value):
    37         print('set--->',instance,value)
    38         instance.__dict__[self.name]=value
    39     def __delete__(self, instance):
    40         print('delete--->',instance)
    41         instance.__dict__.pop(self.name)
    42 
    43 
    44 class People:
    45     name=Str('name')
    46     def __init__(self,name,age,salary):
    47         self.name=name
    48         self.age=age
    49         self.salary=salary
    50 print(People.name) #完美,解决
    51 
    52 拔刀相助
     1 class Str:
     2     def __init__(self,name,expected_type):
     3         self.name=name
     4         self.expected_type=expected_type
     5     def __get__(self, instance, owner):
     6         print('get--->',instance,owner)
     7         if instance is None:
     8             return self
     9         return instance.__dict__[self.name]
    10 
    11     def __set__(self, instance, value):
    12         print('set--->',instance,value)
    13         if not isinstance(value,self.expected_type): #如果不是期望的类型,则抛出异常
    14             raise TypeError('Expected %s' %str(self.expected_type))
    15         instance.__dict__[self.name]=value
    16     def __delete__(self, instance):
    17         print('delete--->',instance)
    18         instance.__dict__.pop(self.name)
    19 
    20 
    21 class People:
    22     name=Str('name',str) #新增类型限制str
    23     def __init__(self,name,age,salary):
    24         self.name=name
    25         self.age=age
    26         self.salary=salary
    27 
    28 p1=People(123,18,3333.3)#传入的name因不是字符串类型而抛出异常
    29 
    30 磨刀霍霍
    class Typed:
        def __init__(self,name,expected_type):
            self.name=name
            self.expected_type=expected_type
        def __get__(self, instance, owner):
            print('get--->',instance,owner)
            if instance is None:
                return self
            return instance.__dict__[self.name]
    
        def __set__(self, instance, value):
            print('set--->',instance,value)
            if not isinstance(value,self.expected_type):
                raise TypeError('Expected %s' %str(self.expected_type))
            instance.__dict__[self.name]=value
        def __delete__(self, instance):
            print('delete--->',instance)
            instance.__dict__.pop(self.name)
    
    
    class People:
        name=Typed('name',str)
        age=Typed('name',int)
        salary=Typed('name',float)
        def __init__(self,name,age,salary):
            self.name=name
            self.age=age
            self.salary=salary
    
    p1=People(123,18,3333.3)
    p1=People('egon','18',3333.3)
    p1=People('egon',18,3333)
    
    大刀阔斧

    大刀阔斧之后我们已然能实现功能了,但是问题是,如果我们的类有很多属性,你仍然采用在定义一堆类属性的方式去实现,low,这时候我需要教你一招:独孤九剑

     1 def decorate(cls):
     2     print('类的装饰器开始运行啦------>')
     3     return cls
     4 
     5 @decorate #无参:People=decorate(People)
     6 class People:
     7     def __init__(self,name,age,salary):
     8         self.name=name
     9         self.age=age
    10         self.salary=salary
    11 
    12 p1=People('egon',18,3333.3)
    13 
    14 类的装饰器:无参
     1 def typeassert(**kwargs):
     2     def decorate(cls):
     3         print('类的装饰器开始运行啦------>',kwargs)
     4         return cls
     5     return decorate
     6 @typeassert(name=str,age=int,salary=float) #有参:1.运行typeassert(...)返回结果是decorate,此时参数都传给kwargs 2.People=decorate(People)
     7 class People:
     8     def __init__(self,name,age,salary):
     9         self.name=name
    10         self.age=age
    11         self.salary=salary
    12 
    13 p1=People('egon',18,3333.3)
    14 
    15 类的装饰器:有参

    终极大招

     1 class Typed:
     2     def __init__(self,name,expected_type):
     3         self.name=name
     4         self.expected_type=expected_type
     5     def __get__(self, instance, owner):
     6         print('get--->',instance,owner)
     7         if instance is None:
     8             return self
     9         return instance.__dict__[self.name]
    10 
    11     def __set__(self, instance, value):
    12         print('set--->',instance,value)
    13         if not isinstance(value,self.expected_type):
    14             raise TypeError('Expected %s' %str(self.expected_type))
    15         instance.__dict__[self.name]=value
    16     def __delete__(self, instance):
    17         print('delete--->',instance)
    18         instance.__dict__.pop(self.name)
    19 
    20 def typeassert(**kwargs):
    21     def decorate(cls):
    22         print('类的装饰器开始运行啦------>',kwargs)
    23         for name,expected_type in kwargs.items():
    24             setattr(cls,name,Typed(name,expected_type))
    25         return cls
    26     return decorate
    27 @typeassert(name=str,age=int,salary=float) #有参:1.运行typeassert(...)返回结果是decorate,此时参数都传给kwargs 2.People=decorate(People)
    28 class People:
    29     def __init__(self,name,age,salary):
    30         self.name=name
    31         self.age=age
    32         self.salary=salary
    33 
    34 print(People.__dict__)
    35 p1=People('egon',18,3333.3)
    36 
    37 刀光剑影

    6 描述符总结

    描述符是可以实现大部分python类特性中的底层魔法,包括@classmethod,@staticmethd,@property甚至是__slots__属性

    描述父是很多高级库和框架的重要工具之一,描述符通常是使用到装饰器或者元类的大型框架中的一个组件.

    7 利用描述符原理完成一个自定制@property,实现延迟计算(本质就是把一个函数属性利用装饰器原理做成一个描述符:类的属性字典中函数名为key,value为描述符类产生的对象)

     1 class Room:
     2     def __init__(self,name,width,length):
     3         self.name=name
     4         self.width=width
     5         self.length=length
     6 
     7     @property
     8     def area(self):
     9         return self.width * self.length
    10 
    11 r1=Room('alex',1,1)
    12 print(r1.area)
    13 
    14 @property回顾
     1 class Lazyproperty:
     2     def __init__(self,func):
     3         self.func=func
     4     def __get__(self, instance, owner):
     5         print('这是我们自己定制的静态属性,r1.area实际是要执行r1.area()')
     6         if instance is None:
     7             return self
     8         return self.func(instance) #此时你应该明白,到底是谁在为你做自动传递self的事情
     9 
    10 class Room:
    11     def __init__(self,name,width,length):
    12         self.name=name
    13         self.width=width
    14         self.length=length
    15 
    16     @Lazyproperty #area=Lazyproperty(area) 相当于定义了一个类属性,即描述符
    17     def area(self):
    18         return self.width * self.length
    19 
    20 r1=Room('alex',1,1)
    21 print(r1.area)
    22 
    23 自己做一个@property
     1 class Lazyproperty:
     2     def __init__(self,func):
     3         self.func=func
     4     def __get__(self, instance, owner):
     5         print('这是我们自己定制的静态属性,r1.area实际是要执行r1.area()')
     6         if instance is None:
     7             return self
     8         else:
     9             print('--->')
    10             value=self.func(instance)
    11             setattr(instance,self.func.__name__,value) #计算一次就缓存到实例的属性字典中
    12             return value
    13 
    14 class Room:
    15     def __init__(self,name,width,length):
    16         self.name=name
    17         self.width=width
    18         self.length=length
    19 
    20     @Lazyproperty #area=Lazyproperty(area) 相当于'定义了一个类属性,即描述符'
    21     def area(self):
    22         return self.width * self.length
    23 
    24 r1=Room('alex',1,1)
    25 print(r1.area) #先从自己的属性字典找,没有再去类的中找,然后出发了area的__get__方法
    26 print(r1.area) #先从自己的属性字典找,找到了,是上次计算的结果,这样就不用每执行一次都去计算
    27 
    28 实现延迟计算功能
     1 #缓存不起来了
     2 
     3 class Lazyproperty:
     4     def __init__(self,func):
     5         self.func=func
     6     def __get__(self, instance, owner):
     7         print('这是我们自己定制的静态属性,r1.area实际是要执行r1.area()')
     8         if instance is None:
     9             return self
    10         else:
    11             value=self.func(instance)
    12             instance.__dict__[self.func.__name__]=value
    13             return value
    14         # return self.func(instance) #此时你应该明白,到底是谁在为你做自动传递self的事情
    15     def __set__(self, instance, value):
    16         print('hahahahahah')
    17 
    18 class Room:
    19     def __init__(self,name,width,length):
    20         self.name=name
    21         self.width=width
    22         self.length=length
    23 
    24     @Lazyproperty #area=Lazyproperty(area) 相当于定义了一个类属性,即描述符
    25     def area(self):
    26         return self.width * self.length
    27 
    28 print(Room.__dict__)
    29 r1=Room('alex',1,1)
    30 print(r1.area)
    31 print(r1.area) 
    32 print(r1.area) 
    33 print(r1.area) #缓存功能失效,每次都去找描述符了,为何,因为描述符实现了set方法,它由非数据描述符变成了数据描述符,数据描述符比实例属性有更高的优先级,因而所有的属性操作都去找描述符了
    34 
    35 一个小的改动,延迟计算的美梦就破碎了

    8 利用描述符原理完成一个自定制@classmethod

     1 class ClassMethod:
     2     def __init__(self,func):
     3         self.func=func
     4 
     5     def __get__(self, instance, owner): #类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身,
     6         def feedback():
     7             print('在这里可以加功能啊...')
     8             return self.func(owner)
     9         return feedback
    10 
    11 class People:
    12     name='linhaifeng'
    13     @ClassMethod # say_hi=ClassMethod(say_hi)
    14     def say_hi(cls):
    15         print('你好啊,帅哥 %s' %cls.name)
    16 
    17 People.say_hi()
    18 
    19 p1=People()
    20 p1.say_hi()
    21 #疑问,类方法如果有参数呢,好说,好说
    22 
    23 class ClassMethod:
    24     def __init__(self,func):
    25         self.func=func
    26 
    27     def __get__(self, instance, owner): #类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身,
    28         def feedback(*args,**kwargs):
    29             print('在这里可以加功能啊...')
    30             return self.func(owner,*args,**kwargs)
    31         return feedback
    32 
    33 class People:
    34     name='linhaifeng'
    35     @ClassMethod # say_hi=ClassMethod(say_hi)
    36     def say_hi(cls,msg):
    37         print('你好啊,帅哥 %s %s' %(cls.name,msg))
    38 
    39 People.say_hi('你是那偷心的贼')
    40 
    41 p1=People()
    42 p1.say_hi('你是那偷心的贼')
    43 
    44 自己做一个@classmethod

    9 利用描述符原理完成一个自定制的@staticmethod

     1 class StaticMethod:
     2     def __init__(self,func):
     3         self.func=func
     4 
     5     def __get__(self, instance, owner): #类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身,
     6         def feedback(*args,**kwargs):
     7             print('在这里可以加功能啊...')
     8             return self.func(*args,**kwargs)
     9         return feedback
    10 
    11 class People:
    12     @StaticMethod# say_hi=StaticMethod(say_hi)
    13     def say_hi(x,y,z):
    14         print('------>',x,y,z)
    15 
    16 People.say_hi(1,2,3)
    17 
    18 p1=People()
    19 p1.say_hi(4,5,6)
    20 
    21 自己做一个@staticmethod

      再看property

    一个静态属性property本质就是实现了get,set,delete三种方法

     1 class Foo:
     2     @property
     3     def AAA(self):
     4         print('get的时候运行我啊')
     5 
     6     @AAA.setter
     7     def AAA(self,value):
     8         print('set的时候运行我啊')
     9 
    10     @AAA.deleter
    11     def AAA(self):
    12         print('delete的时候运行我啊')
    13 
    14 #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
    15 f1=Foo()
    16 f1.AAA
    17 f1.AAA='aaa'
    18 del f1.AAA
    19 
    20 用法一
     1 class Foo:
     2     def get_AAA(self):
     3         print('get的时候运行我啊')
     4 
     5     def set_AAA(self,value):
     6         print('set的时候运行我啊')
     7 
     8     def delete_AAA(self):
     9         print('delete的时候运行我啊')
    10     AAA=property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应
    11 
    12 f1=Foo()
    13 f1.AAA
    14 f1.AAA='aaa'
    15 del f1.AAA
    16 
    17 用法二
     1 class Goods:
     2 
     3     def __init__(self):
     4         # 原价
     5         self.original_price = 100
     6         # 折扣
     7         self.discount = 0.8
     8 
     9     @property
    10     def price(self):
    11         # 实际价格 = 原价 * 折扣
    12         new_price = self.original_price * self.discount
    13         return new_price
    14 
    15     @price.setter
    16     def price(self, value):
    17         self.original_price = value
    18 
    19     @price.deleter
    20     def price(self):
    21         del self.original_price
    22 
    23 
    24 obj = Goods()
    25 obj.price         # 获取商品价格
    26 obj.price = 200   # 修改商品原价
    27 print(obj.price)
    28 del obj.price     # 删除商品原价
    29 
    30 案例一
     1 #实现类型检测功能
     2 
     3 #第一关:
     4 class People:
     5     def __init__(self,name):
     6         self.name=name
     7 
     8     @property
     9     def name(self):
    10         return self.name
    11 
    12 # p1=People('alex') #property自动实现了set和get方法属于数据描述符,比实例属性优先级高,所以你这面写会触发property内置的set,抛出异常
    13 
    14 
    15 #第二关:修订版
    16 
    17 class People:
    18     def __init__(self,name):
    19         self.name=name #实例化就触发property
    20 
    21     @property
    22     def name(self):
    23         # return self.name #无限递归
    24         print('get------>')
    25         return self.DouNiWan
    26 
    27     @name.setter
    28     def name(self,value):
    29         print('set------>')
    30         self.DouNiWan=value
    31 
    32     @name.deleter
    33     def name(self):
    34         print('delete------>')
    35         del self.DouNiWan
    36 
    37 p1=People('alex') #self.name实际是存放到self.DouNiWan里
    38 print(p1.name)
    39 print(p1.name)
    40 print(p1.name)
    41 print(p1.__dict__)
    42 
    43 p1.name='egon'
    44 print(p1.__dict__)
    45 
    46 del p1.name
    47 print(p1.__dict__)
    48 
    49 
    50 #第三关:加上类型检查
    51 class People:
    52     def __init__(self,name):
    53         self.name=name #实例化就触发property
    54 
    55     @property
    56     def name(self):
    57         # return self.name #无限递归
    58         print('get------>')
    59         return self.DouNiWan
    60 
    61     @name.setter
    62     def name(self,value):
    63         print('set------>')
    64         if not isinstance(value,str):
    65             raise TypeError('必须是字符串类型')
    66         self.DouNiWan=value
    67 
    68     @name.deleter
    69     def name(self):
    70         print('delete------>')
    71         del self.DouNiWan
    72 
    73 p1=People('alex') #self.name实际是存放到self.DouNiWan里
    74 p1.name=1
    75 
    76 案例二
  • 相关阅读:
    跃迁方法论 Continuous practice
    EPI online zoom session 面试算法基础知识直播分享
    台州 OJ 2648 小希的迷宫
    洛谷 P1074 靶形数独
    洛谷 P1433 DP 状态压缩
    台州 OJ FatMouse and Cheese 深搜 记忆化搜索
    台州 OJ 2676 Tree of Tree 树状 DP
    台州 OJ 2537 Charlie's Change 多重背包 二进制优化 路径记录
    台州 OJ 2378 Tug of War
    台州 OJ 2850 Key Task BFS
  • 原文地址:https://www.cnblogs.com/pantong/p/10502917.html
Copyright © 2011-2022 走看看