Python廖雪峰教程学习笔记:Day11

前言

养成一个好的习惯只需要坚持21天,Day11
这两天主要学习一下面向对象的高级编程。

使用__slots__

由之前学习类的定义和实例的创建,我们可以给实例绑定不同的属性,例如:

class Student(object):
	pass
s = Student()
s.name = 'Tom' # 动态给实例绑定一个属性
print(s.name)
# Tom

如果我们只允许对Student实例添加name和age属性,达到限制的目的,我们就可以定义一个特殊的__solts__变量,来限制该class实例能添加的属性,接下来Student实例就只能添加name和age属性了:

class Student(object):
	__solts__ = ('name','age') #用tuple定义允许绑定的属性名称

接着进行测试:

s = Student() #创建新的实例
s.name = 'Tom'  # 绑定name属性
s.age = 23      # 绑定age属性
s.score = 90    # 绑定score属性
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# AttributeError: 'Student' object has no attribute 'score'

由于score属性没有被放到__solts__中,所以不能绑定score属性;如果强行绑定就会得到AttributeError错误。不过__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。例如GraduateStudent子类是可以绑定score属性的:

class GraduateStudent(Student):
	paa
g = GraduateStudent()
g.score = 999
print(g.score)
# 90
@property

在绑定属性的时候,我们需要对参数进行检查,比如上面在为对象的score属性赋值999时,显然是不符合我们生活中的分数的。为了限制score的范围,可以通过设置方法来获取和设置成绩,比如set_score()get_score()方法:

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

如上定义后,就不能对score随意设值了。当赋予score的值不是int类型或者超过0-100时就会报错:

s = Student()
s.set_score(90)
print(s.get_score)
# 90
s.set_score(999)
# Traceback (most recent call last):
  ...
# ValueError: score must between 0 ~ 100!

这样的调用略显复杂,在Python中可以使用@property装饰器负责把一个方法变成属性调用,即代替上面的功能:

class Student(object):

    @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 = value

把一个getter方法变成属性,只需要加上@property。此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:

s = Student()
s.set_score(90)
print(s.score)
# 90
s.set_score(999)
# Traceback (most recent call last):
  ...
# ValueError: score must between 0 ~ 100!

下面的例子中birth是可读写属性,而age就是一个只读属性,因为age可以根据birth和当前时间计算出来。

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

练习
请利用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution:

class Screen(object):

    @property
    def width(self):
        return self._width
    @width.setter
    def width(self,value):
        if not isinstance(value,int):
            raise ValueError('width must be integer')
        if value < 0:
            raise ValueError('width must be above 0')
        self._width = value

    @property
    def height(self):
        return self._height
    @height.setter
    def height(self,value):
        if not isinstance(value,int):
            raise ValueError('height must be integer')
        if value < 0:
            raise ValueError('height must be above 0')
        self._height = value

    @property
    def resolution(self):
        return self.width * self.height
# 测试:
s = Screen()
s.width = 1024
s.height = 768
print('resolution =', s.resolution)
if s.resolution == 786432:
    print('测试通过!')
else:
    print('测试失败!')
# resolution = 786432
# 测试通过!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值