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 案例二
  • 相关阅读:
    Word Frequency
    House Robber(动态规划)
    链表的排序 时间复杂度O(nlogn)
    gdb调试(转)
    c实现的trim函数
    c实现的trim函数
    mac下安装pyQt4
    哈夫曼编码详解
    IOS7--javascriptcore中jscontext使用要注意的一点
    Docker mysql 连接 “The server requested authentication method unknown to the clien”错误
  • 原文地址:https://www.cnblogs.com/pantong/p/10502917.html
Copyright © 2011-2022 走看看