Python内置装饰器@property
在《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的一个最直接的作用就是把类方法变为类属性,访问这些方法的返回值时就不用多写个括号了。
Python内置装饰器@property的更多相关文章
- python基础语法16 面向对象3 组合,封装,访问限制机制,内置装饰器property
组合: 夺命三问: 1.什么是组合? 组合指的是一个对象中,包含另一个或多个对象. 2.为什么要用组合? 减少代码的冗余. 3.如何使用组合? 耦合度: 耦: 莲藕 ---> 藕断丝连 - 耦合 ...
- python内置装饰器
前言 接着上一篇笔记,我们来看看内置装饰器property.staticmethod.classmethod 一.property装饰器 1. 普通方式修改属性值 code class Celsius ...
- Python 内置装饰器
内置的装饰器 内置的装饰器和普通的装饰器原理是一样的,只不过返回的不是函数,而是类对象,所以更难理解一些. @property 在了解这个装饰器前,你需要知道在不使用装饰器怎么写一个属性. d ...
- Python之内置装饰器property
# -*- coding: utf-8 -*- # author:baoshan class Student(object): def __init__(self, name): self.name ...
- 面向对象之classmethod和staticmethod(python内置装饰器)
对象的绑定方法复习classmethodstaticmethod TOC 对象的绑定方法复习 由对象来调用 会将对象当做第一个参数传入 若对象的绑定方法中还有其他参数,会一并传入 classmetho ...
- python进阶04 装饰器、描述器、常用内置装饰器
python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...
- property内置装饰器函数和@name.setter、@name.deleter
# property # 内置装饰器函数 只在面向对象中使用 # 装饰后效果:将类的方法伪装成属性 # 被property装饰后的方法,不能带除了self外的任何参数 from math import ...
- classmethod、staticclassmethod内置装饰器函数
# method 英文是方法的意思 # classmethod 类方法 # 当一个类中的方法中只涉及操作类的静态属性时,此时在逻辑上,我们想要直接通过类名就可以调用这个方法去修改类的静态属性,此时可以 ...
- python之内置装饰器(property/staticmethod/classmethod)
python内置了property.staticmethod.classmethod三个装饰器,有时候我们也会用到,这里简单说明下 1.property 作用:顾名思义把函数装饰成属性 一般我们调用类 ...
随机推荐
- jQuery实现类似于购物车操作
先看页面的代码,后面会详细写每一个操作的实现. <html> <head> <title>jQuery操作表格</title> <meta cha ...
- 洛谷 SPOJ 题解 SP1 【TEST - Life, the Universe, and Everything】
给出一种主函数递归的方法(其实主函数 main() 也是可以递归的) #include <stdio.h> int main() { int a; scanf("%d" ...
- 20.DjangoRestFramework学习三之认证组件、权限组件、频率组件、url注册器、响应器、分页组件
一 认证组件 1. 局部认证组件 我们知道,我们不管路由怎么写的,对应的视图类怎么写的,都会走到dispatch方法,进行分发, 在咱们看的APIView类中的dispatch方法的源码中,有个sel ...
- git 中的 merge 和 rebase
示例分支:master . dev 把 dev 分支上的新内容合并到 master 上 先切换分支到master git checkout master 合并操作 git merge dev 或者 g ...
- 解密国内BAT等大厂前端技术体系-携程篇(长文建议收藏)
1 引言 为了了解当前前端的发展趋势,让我们从国内各大互联网大厂开始,了解他们的最新动态和未来规划.这是解密大厂前端技术体系的第四篇,前三篇已经讲述了阿里.腾讯.百度在前端技术这几年的技术发展. 这一 ...
- windows系统的python开发环境的搭建
step1: 访问python官方网站下载python安装包 https://www.python.org/downloads/windows/ 下载自己想要的版本 勾上Add Python XX ...
- Ubuntu 18.04系统中不能ssh外网远程
前言 今天我不小心动了电插板,导致服务器断电,用远程命令开机,居然很长时间没反应,索性就亲自按电源键重启.服务器正常开机启动,ssh可以内网访问,远程命令内网有效果,就是外网不行.经过分析排查,是不是 ...
- LeetCode刷题总结-树篇(下)
本文讲解有关树的习题中子树问题和新概念定义问题,也是有关树习题的最后一篇总结.前两篇请参考: LeetCode刷题总结-树篇(上) LeetCode刷题总结-树篇(中) 本文共收录9道题,7道中等题, ...
- 【后端C#】后台通过http post 调用 webservice 的方法
定义http post 调用webservice的某个方法 /// <summary> /// http Post调用 WebService /// </summary> pu ...
- CefSharp禁止弹出新窗体,在同一窗口打开链接,或者在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接
说明:在同一窗口打开链接,只要稍加改造就可以实现,这里实现的是在新Tab页打开链接,并且支持带type="POST" target="_blank"的链接 gi ...