在《Python装饰器(Decorators )》一文中介绍了python装饰器的概念,日常写代码时有一个装饰器很常见,他就是内置的@property。

我们一步步的来接近这个概念。

一个初始示例如下:

LeosWorkGround项目下有一个名为leo01.py的文件内容如下:

# coding=utf-8
class Student(object):
def __init__(self , first_name , last_name , age , hobby):
self.first_name = first_name
self.last_name = last_name
self.age=age
self.hobby=hobby def __str__(self):
return self.first_name+' '+self.last_name

leo02.py的内容如下:

# coding=utf-8
from LeosWorkGround.leo01 import Student
A = Student('xiao' , 'ming',10,'音乐,读书,打游戏')
print('名字:',A,'爱好:',A.hobby)

咋一看上述代码很合理,但假如我们要修改A的hobby属性怎么办?使用下边一句可以直接修改:

A.hobby='音乐,读书,打游戏,睡觉'

但是有一些人觉得这样的写法很不pythonic!因为在pycharm中你可以清楚地看到A的所有属性都会被自动补全出来。

于是为了能明确的展示出哪些属性可以被修改,我们用单下划线将所有变量设置为弱保护变量并添加一个set_hobby()的方法,表示hobby属性可以set,于是代码改进如下:

# coding=utf-8
class Student(object):
def __init__(self , first_name , last_name , age , hobby):
self._first_name = first_name
self._last_name = last_name
self._age=age
self._hobby=hobby def __str__(self):
return self._first_name+' '+self._last_name def set_hobby(self,hobby):
self._hobby=hobby

好,这样leo02.py就可以通过set_hobby来修改实例的hobby属性了,并且pycharm中也不会自动预测出A的属性们了,你只能看到A实例有个set_hobby的方法,这样最大程度的避免了变量名对外暴露。

虽然依然可以使用A._hobby=xxx修改属性,但至少不是那么容易了。

那相似的,如果要获取_hobby属性,我们为了不让别人直接访问_hobby可以加一个get_hobby的方法,内容很简单:

# coding=utf-8
class Student(object):
def __init__(self , first_name , last_name , age , hobby):
self._first_name = first_name
self._last_name = last_name
self._age=age
self._hobby=hobby def __str__(self):
return self._first_name+' '+self._last_name def set_hobby(self,hobby):
self._hobby=hobby def get_hobby(self):
return self._hobby

熟悉java的应该可以看出很类似于setter与getter方法,本质上讲这种把变量写为弱保护变量并添加get和set方法只是为了解决两个问题:

  • 避免自己写的class里的属性被本组其他程序员调用后随意修改属性值。
  • 明确告诉本组其他程序员,你只能通过我写好的set和get方法来修改和获取某些属性的值。

到这里以上两个问题基本解决,但是有人依然觉得这不Pythonic!!!于是@property装饰器出现了。

这个装饰器的出现是为了解决什么问题呢?

  • 使你可以不暴露class的内部属性名称,其他人依然可以修改某个属性

直接提出修改后的代码:

# coding=utf-8
class Student(object):
def __init__(self , first_name , last_name , age , hobby):
self._first_name = first_name
self._last_name = last_name
self._age=age
self._hobby=hobby def __str__(self):
return self._first_name+' '+self._last_name @property
def hobby(self):
return self._hobby @hobby.setter
def hobby(self,hobby):
self._hobby=hobby

这里@property其实就相当于get方法,之后的@hobby.setter就相当于set方法,在使用@property装饰器装饰hobby()后,你就可以调用@hobby.setter了。

比较一下与上述set_hobby,get_hobby代码的区别,其实区别很小,一是不再对外提供set和get方法,二是可以直接通过给属性赋值来修改内置属性,虽然这个对外暴露的属性其实是一个method。

# coding=utf-8
from LeosWorkGround.leo01 import Student
A = Student('xiao' , 'ming',10,'音乐,读书,打游戏')
A.hobby='音乐,读书,打游戏,睡觉'
print('名字:',A,'爱好:',A.hobby)

总结:

@property的作用主要是隐藏类的内部属性,并对外提供这些属性的修改接口,同时避免了每个要修改的属性都有两个set和get方法的麻烦。

最终对外的展示效果就是,只需要为对外暴露的属性赋值就可以直接修改其内部属性值,一句话:你能看到的都是我想让你看到的。

最后,@property的一个最直接的作用就是把类方法变为类属性,访问这些方法的返回值时就不用多写个括号了。

最新文章

  1. MySQL(三)
  2. UI第十六节——UITabBarController详解
  3. linux操作oracle
  4. MC的分布式算法的实现和一些总结
  5. php base64 原理
  6. 深入浅出Redis02 使用Redis数据库(String类型)
  7. Android学习系列(36)--App调试内存泄露之Context篇(上)
  8. Tomcate配置单向双向SSL
  9. linux ps命令介绍
  10. struct inode 和 struct file
  11. OpenJudge/Poj 1083 Moving Tables
  12. 【Java】Java Platform
  13. C学习-fgets()篇1
  14. 【网络流量-二部图最大匹配】poj3041Asteroids
  15. Web Components
  16. CodeForces 710E Generate a String
  17. 在TTF字体中提取想要的文字
  18. js中原生对象、内置对象和宿主对象(转)
  19. IOS开发-UI学习-UITabBarController的使用
  20. Zabbix实战-简易教程(9)--模板

热门文章

  1. go实践之swagger自动生成api文档
  2. IntelliJ IDEA 2019.3安装激活破解使用教程
  3. io流函数略解(java_input流)[二]
  4. GlusterFS 存储
  5. java_计算个人所得税
  6. MySQL的安装、启动和基础配置 —— windows版本
  7. Redis主从复制架构和Sentinel哨兵机制
  8. Codeforces Round #591 (Div. 2)
  9. 《Java数据结构》树形结构
  10. Nezuko: 1 Vulnhub Walkthrough