zoukankan      html  css  js  c++  java
  • @property的用法

    实例的属性有些是需要进行约束的,比如分数、年龄都需要是整形,而不能是浮点数类型,因此为了约束这些属性的取值,可以在类的定义中定义赋值和取值函数,在赋值函数中对变量的取值进行约束,如下所示

    class Student(object):
    
        def get_score(self):
             return self._score
    
        def set_score(self, value):
            if not isinstance(value, int):
                raise ValueError('score must be an integer!')
            if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
            self._score = value
    

    但是这么做每次对变量赋值都需要调用函数,能否不调用函数,而直接像使用属性一样取值赋值呢,答案是可以的,就需要用到@property

    class Junior(object):
        def __init__(self, name, score, sex, height, weight):
            self.name = name
            self.score = score
            self.sex = sex
            self.height = height
            self.weight = weight
        @property
        def birth(self):
            return self._birth
        @birth.setter
        def birth(self,year):
            if not isinstance(year,int):
                raise valueerror('not integer')
            self._birth=year
        @property
        def age(self):
            return 2017-self._birth

    s=Junior('kimi',96,'M',180,65)

    s.birth=1989
    print(s.birth)
    print(s.age)

    上例中就可以将birth当做属性来调用赋值,又可以对它进行约束,这个例子中birth属于可读可写,而age只有@property,没有setter,因此只是可读,不能赋值。

    作业:

    class Screen(object):
        @property
        def width(self):
            return self._width
        @property
        def height(self):
            return self._height
        @width.setter
        def width(self,value):
            if not isinstance(value,int):
                raise error('not an integer')
            self._width=value
        @height.setter
        def height(self, value):
            if not isinstance(value, int):
                raise error('not an integer')
            self._height = value
        @property
        def resolution(self):
            self._resolution=self.width*self.height
            return self._resolution
    # test:
    s = Screen()
    s.width = 1024
    s.height = 768
    print(s.resolution)
    assert s.resolution == 786432, '1024 * 768 = %d ?' % s.resolution
    

    取值和赋值函数内部的变量不能与函数名相同,一定要有所区分,不然会被认为是函数名,导致出问题,因此函数名为width,函数内部的变量名为self._width  

    以下做了一个实验:

    class Dog(object):
        __slots__=('_name','_spec','_birth')
        def __init__(self,name,spec='Unknown'):
            self._name=name
            self._spec=spec
        @property
        def _age(self):
            return 2017-self._birth
        @property
        def birth(self):
            return self._birth
        @birth.setter
        def birth(self,year):
            if not isinstance(year,int):
                raise Error('Wrong')
            else:
                self._birth=year
    dd=Dog('didi','wolf')
    dd._birth=2000
    print(dd.birth)
    dd.birth=2000
    print(dd.birth)
    print(dd._age)
    

    __slot__针对的是self的属性,不包括方法名,但是方法类的属性名也需要包括进去,比如birth不属于,而_birth就属于约束范围,属性方法birth在函数外调用时用birth名,但是在函数内部属性需要另取他名,否则会和函数名相同,导致反复调用,程序崩溃,上例中可以使用birth和_birth赋值,但是两者走的路径不同,birth是属性方法赋值,而_birth是直接给属性赋值

      

      

      

  • 相关阅读:
    MS-DOS命令
    寻找一条通过迷宫的路径
    linux文件基本操作和常用命令
    网络基础
    计算机基础---操作系统
    GIT 使用
    计算机基础
    秒角士网站
    咖啡项目
    winfrom面向对象1
  • 原文地址:https://www.cnblogs.com/vonkimi/p/6938309.html
Copyright © 2011-2022 走看看