前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个例子带你入门Python装饰器

一个例子带你入门Python装饰器

作者头像
刘早起
发布2020-04-22 16:39:57
3280
发布2020-04-22 16:39:57
举报
文章被收录于专栏:早起Python早起Python

前言

在还未正式发布的python3.9中,有一个新功能值得关注,那就是任意表达式可以作为装饰器,如果你还不知道装饰器是什么,没关系,跟着本文一个例子搞明白,不过需要你对Python中的类(Class)有一定的了解,因为我们一般在类中使用。

一个例子

关于装饰器是什么,随便一搜都能找到一堆解释。我们让那些看着头疼的名词、定义去一边吃灰,看下面这个例子

代码语言:javascript
复制
class Blog():
    
    def __init__(self,name,title):
        self.author = name
        self.article = title
        self.information = self.author + ' ' + self.article
    
    def url(self):
        return f"The author url is {self.author}.{self.article}.com "

这段代码不难理解吧,定义了一个Blog类,这个类包含author、article、information属性,并拥有一个url方法。

现在我们来创建一个实例

代码语言:javascript
复制
>>> user = Blog('liuzaoqi','Python')

这行代码不难看懂吧,创建了一个user,姓名是liuzaoqi,标题是Python。OK现在来打印一下相关属性

代码语言:javascript
复制
>>> print(user.author)
#liuzaoqi
>>> print(user.article)
#Python
>>> print(user.information)
#liuzaoqi Python
>>> print(user.url())
#The author url is liuzaoqi.Python.com

没问题吧,到目前为止还与装饰器没啥太大关系,现在问题来了,如果我想修改这个user的article,这样写可以吧?

代码语言:javascript
复制
>>> user.article = 'study'
>>> print(user.article)
>>> print(user.information)
>>> print(user.url())

来猜一下结果,我们将article修改了:将'Python'改为'study'

而information与url都与article有关,因此它们都应该随之修改,来看看结果?

代码语言:javascript
复制
study
liuzaoqi Python
The author url is liuzaoqi.study.com

你神奇的事情发生了,都是由article生成的,但是只有url修改了,information并没有发生变化,这是因为:在Python中如果我们更改了类中的一个属性的值,那么从刚刚更改的属性生成的其他属性不会自动更新。

那要怎么解决呢?我们注意到url能够正确的改变,那我们将information由属性改为方法不就OK了,因此代码就改成了这样

代码语言:javascript
复制
class Blog():
    
    def __init__(self,name,title):
        self.author = name
        self.article = title
    
    def information(self):
        return self.author + ' ' + self.article
    
    def url(self):
        return f"The author url is {self.author}.{self.article}.com "

能看懂吧,不就是将information由属性改为方法,现在再来试一下?

代码语言:javascript
复制
>>> user = Blog('liuzaoqi','Python')
>>> print(user.information())
#liuzaoqi Python
>>> user.article = 'study'
>>> print(user.information())
#liuzaoqi study

还是同样的操作,但是现在information就可以随着article修改而自动更新了。

等等,到这里好像与装饰器没啥关系啊。但是你有没有发现,我们之前调用information使用的是user.information但是现在变成了user.information(),多了一个(),别小瞧这个括号,如果我们正在开发一个大型项目,那么我们这样一修改,哦吼,所有使用了user.information的代码都将崩溃。

这是就需要装饰器登场了,Python中内置装饰器@property可以在方法的定义之前添加装饰器将方法转换为属性?

代码语言:javascript
复制
class Blog():
    
    def __init__(self,name,title):
        self.author = name
        self.article = title
    
    @property 
    def information(self):
        return self.author + ' ' + self.article
    
    def url(self):
        return f"The author url is {self.author}.{self.article}.com "

不用仔细看,就加了一句@property在方法上面,OK,现在再来看看?

代码语言:javascript
复制
>>> user = Blog('liuzaoqi','Python')
>>> print(user.information)
#liuzaoqi Python
>>> user.article = 'study'
>>> print(user.information)
#liuzaoqi study

现在我们就能使用访问属性的方法来调用information,这就是装饰器,它就是负责把一个方法变成属性调用。但是这是可能还有一个问题,现在修改name、article之后information会自动更新,但是如果我们修改information属性则name和article自动更新吗,就像这样?

代码语言:javascript
复制
>>> user.information = 'zaoqi python'
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-57-00cd34ab7d23> in <module>
----> 1 user.information = 'zaoqi python'

AttributeError: can't set attribute

很遗憾,并不能如我们预想的一样,当然解决这个问题并不困难,使用setter/deleter方法就可以,这会在之后的文章中讲解,至少读到这里我们已经学会装饰器是个什么玩意,不是吗?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 早起Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档