使用__slots__;类的装饰器@property

之前我们可以给实例绑定属性,但是能不能给实例绑定方法呢??

class Hero(object):
    pass

hero=Hero()
def setheroav_age(self, age):  # 定义一个函数作为实例方法
    self.age = age

from  types import MethodType
hero.setheroav_age=MethodType(setheroav_age,hero) #把setheroav_age绑定给hero
hero.setheroav_age(100)#调用实例方法
print(hero.age)
print(hasattr(hero,'setheroav_age'))
#>> 100
#>> True

如果你想限制实例的属性怎么办呢??
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性,:
譬如只运行对name和age添加属性

class Hero(object):
    __slots__ = ('name','age')#只允许绑定的属性名称

hero=Hero()
hero.name='tony'
hero.age=25
hero.rank=3
print(hero.name,hero.age,hero.rank)
#>> 显示rank不在attribute之内

对于类的方法,装饰器一样起作用。Python内置的@property装饰器就是负责把一个方法变成属性调用的
背景:我们之前的类的属性是可以随便被更改的,为了解决这个问题,我们在类里面增加两个函数,


class Hero(object):
      def getSelf_name(self):
          return self._name
      def setSelf_name(self,name):
          heroname=['tony','thor','hulk']
          if name not in heroname:
             self._name=name
             heroname.append(name)
           else:
              raise ValueError('name must not in heroname!')
           
hero=Hero()
hero.setSelf_name('spider_man')
print(hero.getSelf_name())

hero.setSelf_name('tony')
print(hero.getSelf_name())
          

使用__slots__;类的装饰器@property_第1张图片但是这样感觉很复杂,能不能简洁一丢丢呢?Python内置的@property装饰器就是负责把一个方法变成属性调用的:
在程序上的体现就是:

class Hero(object):
    @property #位置是在第一个
    def Self_name(self): #注意:第一个函数名和下面那个相同的哦
        return self._name

    @Self_name.setter
    def Self_name(self, name):
        heroname = ['tony', 'thor', 'hulk']
        if name not in heroname:
            self._name = name
            heroname.append(name)
        else:
            raise ValueError('name must not in heroname!')

hero = Hero()
# hero.setSelf_name('spider_man') 这是是之前的
hero.Self_name='spider_man' #用上装饰器之后,函数名就相当于一个‘属性’
print(hero.Self_name)
#>> spider_man       

这个神奇的 @property,我们在对实例属性操作的时候,就知道该属性很可能不是直接暴露的,而是通过getter和setter方法来实现的。
通过装饰器,可以对‘函数变成的属性’进行可读写or只读只写得属性。譬如:

class Hero(object):
    @property #位置是在第一个
    def Self_name(self): #注意:第一个函数名和下面那个相同的哦
        return self._name

    @Self_name.setter
    def Self_name(self, name):
        heroname = ['tony', 'thor', 'hulk']
        if name not in heroname:
            self._name = name
            heroname.append(name)
        else:
            raise ValueError('name must not in heroname!')
     @property
     def decoratename(self):
         return 'I am avengers'+str(self._name)

hero = Hero()
# hero.setSelf_name('spider_man') 这是是之前的
hero.Self_name='spider_man' #用上装饰器之后,函数名就相当于一个‘属性’
print(hero.Self_name)
print(hero.decoratename)

使用__slots__;类的装饰器@property_第2张图片

你可能感兴趣的:(Python,python)