python学习之类和实例的属性;装饰器@property

  1. 无论是类还是实例,一切皆是对象。
  2. Python是强动态语言,和java在这点上有所不同。
class Ab():
    a = 666

# 定义类对象Ab,自带属性a,值为666
# 使用Ab.__dict__可以查看类Ab的属性

us1 = Ab()
us2 = Ab()

# 定义两个实例对象us1、us2,这两个实例自身并不具备任何属性
# 只有在__init__中定义了self.arg=xxx的情况下,实例默认会具备arg属性
  1. 动态语言中,属性自带操作方法:获取(读)、设置(写);还可以定义删除
print(Ab.a, us1.a, us2.a)

# 获取属性a,输出均为666
# 属性查找机制:自下而上。
# python查找对象us1不具备属性a,就会在其所属的类对象Ab中查找属性a。

us1.a += 333

# 输出999
# 首先查找us1.a未找到,于是使用Ab.a
# 然后设置Ab.a+333的值为us1.a属性的值

Ab.a += 222

# 输出888

print(Ab.a, us1.a, us2.a)

# 输出分别为888,999, 888
# us1已具备属性a,值为999.所以不再类中查找
# us2不具备属性a,所以使用类Ab.a的值

@property

将类的方法变为属性

  1. 原因:

不使用方法限制属性,则属性可以随意读写;
使用方法限制读写,则读写比较麻烦(要调用三个方法:get、set、del)

  1. 解决方法:装饰器property

将方法转化为属性,即方便调用,又防止随意更改。

  1. 示例
class Student(object):

    @property
    def score(self):
    '''
    原本定义为get_score()
    调用方法:xiaopang.get_score()
    如今调用属性score:xiaopang.score
    '''
        return self._score
    
    @score.setter
    def score(self, value):
    '''
    原本定义为set_score()
    调用方法:xiaopang.set_score(80)
    如今调用属性score:xiaopang.score = 80
    '''
        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
  1. property原理
  • 并没有直接暴露属性,而是通过property的getter、setter方法进行参数传递
  • dir(property)查看到还有deleter方法,如果只有getter(默认),没有setter,则属性为只读
posted @ 2018-07-17 19:33  今天阳光那么好  阅读(857)  评论(0编辑  收藏  举报