Python-管理实例属性

在实际面向对象编程的过程中,实例对象的属性通常都有一定的存储逻辑。例如,学校管理系统中,学生的信息管理。我们需要记录学生的姓名,年龄,各科的成绩。然后还要根据各科的来判断该学生是否能够正常毕业。定义一个学生类可以这样:

class Student(object):

    def __init__(self,name,age,grades):
        self.name = name
        self.age =age
        self.grades =grades

    def graduate(self):
        if self.grades >= 60:
            print("允许毕业")
        else:
            print("留级查看")

但这样似乎不是很合理,因为像年龄,学习成绩这些应该都是正整数,当我们录入这些信息的时候可能会出错。为了防止这种情况的发生,我们必须对age和grades进行限制。
最常用的就是get()和set()方法
1 不能通过"."直接访问属性,需要将属性私有化,python中的做法是在属性前加双下划线
2 提供get()和set()方法,以限制存储规则
如下:

class Student(object):

    def __init__(self,name,age,grades):
        self.__name = name
        self.__age =age
        self.__grades =grades

    def get_name(self):
        return self.__name

    def set_name(self,name):
        self.__name = name

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if isinstance(age,int) and age > 0:
            self.__age = age

    def get_grades(self):
        return self.__grades

    def set_grades(self, grades):
        if isinstance(grades,int) and grades > 0:
            self.__grades = grades

    def graduate(self):
        if self.grades >= 60:
            print("允许毕业")
        else:
            print("留级查看")

这样写我们就age和grades存储的合理性 ,但也存在一些弊端:

  • 我们不能通过“.”来访问属性
  • 我们每一个属性都要写set和get方法,比较费劲
  • 如果需要添加新的属性,还需要添加set和get方法
  • 当我们要修改某个属性的时候,寻找对应的set和get方法比较费时间

通过property装饰器管理属性

class Student(object):

    def __init__(self,name,age,grades):
        self.name = name
        self.age =age # 调用age.setter方法
        self.grades =grades

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self,name):
        self.__name = name

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if isinstance(age,int) and age > 0:
            self.__age = age
        else:
            raise ValueError("数值输入异常")

    @property
    def grades(self):
        return self.__grades

    @grades.setter
    def grades(self, grades):
        if isinstance(grades,int) and grades > 0:
            self.__grades = grades
        else:
            raise ValueError("数值输入异常")

    def graduate(self):
        if self.grades >= 60:
            print("允许毕业")
        else:
            print("留级查看")

s = Student("jack",22,88)
s.grades = 33
print(s.grades)
  • 函数在使用@property 装饰器装饰后,会变成类属性,而且会有一个 setter 方法,装饰同属性的 set 函数。被装饰的函数必须与属性(被@property 装饰器装饰的函数)同名
  • 在给属性赋值的时候,执行的是setter函数。例如__init__方法中的self.age = age 执行的是装饰器@age.setter装饰的函数
  • 访问属性的时候,执行的是装饰器@property装饰的函数,例如访问self.age 执行的是装饰器@property装饰的age()函数
  • @property装饰的函数age返回的是self.__age而不是self.age,如果返回self.age 相当于执行了通过@property装饰的函数age,这会导致无限递归
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值