Python面向对象学习(3):

来源:互联网 发布:淘宝嘉贝逸飞旗舰店 编辑:程序博客网 时间:2024/05/18 17:57

[0]@property的使用,我们对于一些变量的设置是不希望它们暴露在外部的.因此设置了很多方法去设置这些属性,更改它们.这样可以进行一些必要的检查.但是相对于直接用变量去赋值就显得不那么简洁.所以Python内置的一种装饰器Property可以让我们像使用属性一样使用方法:

[1]:property对get方法装饰的结果就是把这个方法的名字变成了一个属性(get_score).为了简洁,我们可以把get_score改为score,这样从外部开起来就像是直接使用了这个score属性一样.

class Student(object):    def __init__(self,score):        self.__score = score    @property    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 = values = Student(60)print(s.get_score)

[2]:Propery本省会创建一个xxx.setter,这个装饰器的作用就是负责把一个方法变成属性赋值.于是我们从外面看起来就好像可以对属性直接赋值了(其实还是调用了set_score方法)

class Student(object):    def __init__(self,score):        self.__score = score    @property    def get_score(self):        return self.__score    @get_score.setter    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 = values = Student(60)print(s.get_score)s.set_score = 99print(s.get_score)

[3]为了简洁和美观,我们最后的代码如下:

class Student(object):    def __init__(self,score):        self.__score = score    @property    def score(self):        return self.__score    @score.setter    def 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 = values = Student(60)print(s.score)#s.score()s.score = 99#s.score(99)print(s.score)

[4]注意,我们还可以让该属性变成只读属性,也就是指定义getter方法,不定义setter方法.这样你就没有办法修改只读属性,因为只读属性实际上是调用方法后的返回值,它是计算出来的.

class Student(object):    @property    def birth(self):        return self._birth    @birth.setter    def birth(self, value):        self._birth = value    @property    def age(self):        return 2015 - self._birth

下面是一个窗口类的设计

[0]首先进行类型检查,将类型检查设计为一个小的函数,注意,哪怕这个函数只在类内使用,也要加self参数,这和C++不一样(类内不需要加this).

[1]然后对每一个参数的改变都要进行检查!.同时注意区分__width和width,如果你在类内使用width的话可能会导致无限递归.

class Screen(object):    def __init__(self,width = 0,height = 0):        self.check(width,'width')        self.check(height,'height')        self.__width,self.__height = width,height    def check(self,value,name):        if not isinstance(value,(int,float)):            raise TypeError(name,'the width must be int or float')        if (value<0):            raise ValueError(name,'should be positive')    @property    def width(self):return self.__width    @width.setter    def width(self,width):        self.check(width,'width')        self.__width = width    @property    def height(self):return self.__height    @height.setter    def height(self,height):        self.check(height,'height')        self.__height = height    @property    def resolution(self):        return self.__width*self.__heights = Screen()s.width = 1024s.height = 12.8print(s.resolution)assert s.resolution == 786432, '1024 * 768 = %d ?' % s.resolution
0 0
原创粉丝点击