• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

python 清菡 1880次浏览 0个评论

坚持原创输出,点击蓝字关注我吧

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

作者:清菡
博客:oschina、云+社区、知乎等各大平台都有。

由于微信公众号推送改为了信息流的形式,防止走丢,请给加个星标 ⭐,你就可以第一时间接收到本公众号的推送!

目录

  • 一、多个装饰器装饰同一个函数
  • 二、Python 中类里面三个内置的装饰器
    • 1.@classmethod
    • 2.@staticmethod
    • 3.@property
  • 三、3个内置装饰器的演示代码

一、多个装饰器装饰同一个函数

import time
def wrapper(func):
    def count_time(*args,**kwargs):
        print("计算时间的装饰器")
        start_time=time.time()
        func(*args,**kwargs)
        end_time=time.time()
        print("函数运行的时间为:{:.5f}".format(end_time-start_time))
    return count_time

with open("zy/user.txt") as f:
    users=eval(f.read())

def login_check(func):
    def ado(*args,**kwargs):
        print("登录校验的装饰器")
        if not users["token"]:
            print("-----登录页面-------")
            username=input("账号:")
            password=input("密码:")
            if users["user"] == username and users["pwd"] == password:
                users["token"] =True
                func(*args,**kwargs)
        else:
            func()
    return ado

@login_check # 第二步进行装饰  count_time---->func=login_check(func)    func指向的是ado这个函数
@wrapper  #  第一步进行装饰  func=wrapper(func)  func指向的是count_time这个函数。
def func():
    time.sleep(3)
    print("这是是需要被装饰器的函数")

#  从下往上装饰,从上往下执行
func()

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

装饰的时候是从下往上装饰,从上往下执行。 运行的时候是:1.先运行@login_check,2.运行@wrapper,3.再运行time.sleep(3)

二、Python 中类里面三个内置的装饰器

这个三个内置的装饰器是在类里面用的。

1.@classmethod

classmethod装饰了之后,该方法就是一个类方法。

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

self出现了下划波浪线,说明它不符合 pep8 规范。

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

被装饰之后它是一个类方法,那么这个时候self不会代表实例本身,不是实例对象了。那么这个参数改成cls

类方法的第一个参数是cls,代表的是类本身。self 代表的是实例本身。

用类不能调用实例的方法:

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

被 classmethod 装饰了之后,类就能直接调用了:

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

classmethod 装饰之前:实例方法、实例属性,类都是调用不了的。

2.@staticmethod

静态方法,默认不需要传参数(不会传类也不会传实例对象),实例和类都可以调用。

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

3.@property

这个一般用来做设置只读属性的。

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

通过__init__设置的属性,在外面可以读也可以改。

比如给实例设置个属性,这个属性只能读,不能改。那这个属性就设置在@property里面。

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

这个是不能改的,改了以后运行会报错:

测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》

要设置可读属性的话,通过这种方式,实际上设置的是个方法,方法内部返回的是个值。

这个值,就可以把它看成一个只读属性。这个只能读不能改,哈哈哈。

三、3个内置装饰器的演示代码

class MyTest(object):

    def __init__(self,name):#设置一个初始化属性叫做name
        self.name = name

    @classmethod  # 被classmethod装饰了之后,该方法就是一个类方法
    def add(cls):# cls  代表的是类本身
        print("add")
        print(cls)

    @staticmethod  # 静态方法   实例和类都可以调用
    def static():
        print("这个是静态方法")

    @property  # 设定只读属性
    def read_attr(self):
        print("这个装饰器装饰完了之后,该方法可以像属性一样被调用")
        return  "20岁"

    def sub(self):# self 代表的是实例本身
        print("sub中的self",self)

# MyTest.static() #类调用

t= MyTest("qinghan")
# 通过name可以访问到这个属性,可以对这个属性进行更改
t.name="lily"
# print(t.name)
# t.read_attr="19岁"
print(t.read_attr)
# t.static()#实例调用
# t.add()
# t.sub()

公众号清菡软件测试首发,更多原创文章:清菡软件测试 117+原创文章,欢迎关注、交流,禁止第三方擅自转载。


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明测开之函数进阶· 第8篇《多个装饰器装饰同一个函数,三个内置的装饰器》
喜欢 (0)

您必须 登录 才能发表评论!

加载中……