精华内容
下载资源
问答
  • 心得:遇到难以理解的东西,我愿意花费更多的时间去达到我想要目的,那怕会很辛苦。 装饰器 先说说装饰器,装饰器今天看了好多篇资料才彻底理解它含义,但它真正作用是用来装饰函数或者类,在其基本...

    心得:遇到难以理解的东西,我愿意花费更多的时间去达到我想要的目的,那怕会很累很辛苦。

    装饰器
    先说说装饰器,装饰器今天看了好多篇的资料才彻底理解它的含义,但它真正的作用是用来装饰函数或者类,在其基本的方法下增加新的方法,不改变原方法。

    一般而言,我们要想拓展原来函数代码,最直接的办法就是侵入代码里面修改,例如:

    import time
    def f():
        print("hello")
        time.sleep(1)
        print("world")  
    

    这是我们最原始的的一个函数,然后我们试图记录下这个函数执行的总时间,那最简单的做法就是改动原来的代码:

    import time
    def f():
        start_time = time.time()
        print("hello")
        time.sleep(1)
        print("world")
        end_time = time.time()
    
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" %execution_time)
    

    但是实际工作中,有些时候核心代码并不可以直接去改,所以在不改动原代码的情况下,我们可以再定义一个函数。(但是生效需要再次执行函数)

    import time
    
    def deco(func):
        start_time = time.time()
        f()
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" %execution_time)
    
    def f():
        print("hello")
        time.sleep(1)
        print("world")
    
    if __name__ == '__main__':
    
        deco(f)
        print("f.__name__ is",f.__name__)
        print() 
    

    这里我们定义了一个函数deco,它的参数是一个函数,然后给这个函数嵌入了计时功能。但是想要拓展这一千万个函数功能,

    就是要执行一千万次deco()函数,所以这样并不理想!接下来,我们可以试着用装饰器来实现,先看看装饰器最原始的面貌。

    import time
    
    def deco(f):
        def wrapper():
            start_time = time.time()
            f()
            end_time = time.time()
            execution_time = (end_time - start_time)*1000
            print("time is %d ms" %execution_time )
        return wrapper
    
    @deco
    def f():
        print("hello")
        time.sleep(1)
        print("world")
    
    if __name__ == '__main__':
        f()
    

    这里的deco函数就是最原始的装饰器,它的参数是一个函数,然后返回值也是一个函数。

    其中作为参数的这个函数f()就在返回函数wrapper()的内部执行。然后在函数f()前面加上@deco,

    f()函数就相当于被注入了计时功能,现在只要调用f(),它就已经变身为“新的功能更多”的函数了,

    (不需要重复执行原函数)。

    扩展1:带有固定参数的装饰器

    import time
    
    def deco(f):
        def wrapper(a,b):
            start_time = time.time()
            f(a,b)
            end_time = time.time()
            execution_time = (end_time - start_time)*1000
            print("time is %d ms" % execution_time)
        return wrapper
    
    @deco
    def f(a,b):
        print("be on")
        time.sleep(1)
        print("result is %d" %(a+b))
    
    if __name__ == '__main__':
        f(3,4)
    

    扩展2:无固定参数的装饰器

    import time
    
    def deco(f):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            res = f(*args, **kwargs)
            end_time = time.time()
            execution_time_ = (end_time - start_time)*1000
            print("time is %d ms" %execution_time)
            return res #函数的返回值(函数内return后才可以接收)
        return wrapper
    
    
    @deco
    def f(a,b):
        print("be on")
        time.sleep(1)
        print("result is %d" %(a+b))
        return 1  #函数的返回值(这里的值)
    
    @deco
    def f2(a,b,c):
        print("be on")
        time.sleep(1)
        print("result is %d" %(a+b+c))
    
    
    if __name__ == '__main__':
        f2(3,4,5)
        f(3,4)
    

    多个装饰器存在时,自下而上一个一个的去装饰

    def dec1(func):
        print("1111")
        def one():
            print("2222")
            func()
            print("3333")
        return one
     
    def dec2(func):
        print("aaaa")
        def two():
            print("bbbb")
            func()
            print("cccc")
        return two
     
    @dec1
    @dec2
    def test():
        print("test test")
     
    test()
    结果:
    aaaa
    1111
    2222
    bbbb
    test test
    cccc
    3333
    

    带参数的装饰器:

    # -*- coding: UTF-8 -*-
    """"=================================================
    @Project -> File   :Django -> 二叉树之有序列表
    @IDE    :PyCharm
    @Author :爱跳水的温文尔雅的laughing
    @Date   :2020/4/2 21:56
    @Desc   :
    =================================================="""
    import time
    
    
    def out_args(out_args):
        def wrapper(f):
            def wrapper(*args, **kwargs):
                start_time = time.time()
                print(out_args)
                res = f(*args, **kwargs)
                end_time = time.time()
                execution_time_ = (end_time - start_time) * 1000
                print("time is %d ms" % execution_time_)
                return res  # 函数的返回值(函数内return后才可以接收)
            return wrapper
        return wrapper
    
    
    @out_args("外部参数")
    def f(a, b):
        print("be on")
        time.sleep(1)
        print("result is %d" % (a + b))
        return 1  # 函数的返回值(这里的值)
    
    if __name__ == '__main__':
        c=f(1,2)
        print("c",c)
    
    #输出
    外部参数
    be on
    result is 3
    time is 1000 ms
    c 1
    


    Python内置装饰器

    在Python中有三个内置的装饰器,和类有关:

    类属性:
    属于类的公有属性;用类名调用,用类名修改可以永久性修改类属性;和用实例调用结果一样,用实例修改,只能修改当前实例的类属性。

    实例属性:
    实例属性可以被实例方法用,使用方法为self.x

    实例方法:
    定义的方法,可以调用类属性和实例属性

    类方法:
    classmethod 使用装饰器进行装饰,接收的第一个参数为类的本身,主要用于对参数的预处理,可以访问类的属性。

    类中的静态方法:
    staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用

    property:
    property 是属性的意思,表示可以通过通过类实例直接访问的信息

    当我们传入的参数,为一串字符串,并不符合对象属性接收的参数,我们的类属性就派上了用场,进行参数的预处理和访问类属性。

    import re
    class People():
    	nation="china" #类属性
    
    	def __init__(self,name,age):
    		self.name=name  #实例属性
    		self.__age=age #设置私有变量
    
    	def get_info(self):  #实例方法
    		print(self.name,self.__age)
    
    	@classmethod  #类方法
    	def pre_args(cls,obj,nation): #传递参数
    		name=re.findall(r'\w+',obj)[0]
    		age=re.findall(r'\d+',obj)[0]  
    		person=cls(name,age)  #实例化
    		print(cls.nation)
    		return person
    
    	@staticmethod  #静态方法
    	def cal(a,b):
    		print("两数之和为:",a+b)
    
    	@property  #可以访问私有变量
    	def change_age(self):
    		return self.__age
    
    p1=People.pre_args("@tianjian#27","nation")  #直接用类调用类方法
    print(p1)
    p1.get_info()
    
    People.cal(3,5)  #调用静态方法
    
    p2=People("tian",26)
    print(p2.change_age)
    print(p2.__age) #不能访问私有变量
    

    结果:
    私有变量不能直接被访问

    china
    <__main__.People object at 0x7f2d8beaacc0>
    tianjian 27
    两数之和为: 8
    26
    Traceback (most recent call last):
      File "cls_usage.py", line 67, in <module>
        print(p2.__age)
    AttributeError: 'People' object has no attribute '__age'
    
    展开全文
  • 你必须知道495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    5.17 说真的,真有机器用非零空指针吗,或者不同类型用不同的表示? 地址0上到底有什么? 5.18 运行时的整数值0转换为指针以后一定是空指针吗? 5.19 如何访问位于机器地址0处的中断向量?如果我将指针值设为0...
  • 疯狂程序员

    热门讨论 2012-07-18 18:05:32
    因为佩服他,跟他说了很多客套话,没想到一客套,让那男人更牛B起来:“想我堂堂一个程 序员,现在却在搞这个。唉……” 这时候,绝影才第一次听到“程序员”这个词。程序员是什么?他不知道。他问:“程序员能找到...
  • 《你必须知道495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    内容简介 《你必须知道的495个C语言问题》以问答...5.17 说真的,真有机器用非零空指针吗,或者不同类型用不同的表示? 61 地址0 上到底有什么? 61 5.18 运行时的整数值0转换为指针以后一定是空指针吗? 61 5.19...
  • 5.17 说真的,真有机器用非零空指针吗,或者不同类型用不同的表示? 61 地址0 上到底有什么? 61 5.18 运行时的整数值0转换为指针以后一定是空指针吗? 61 5.19 如何访问位于机器地址0处的中断向量?如果我将...
  • 用 jQuery 代码中就混杂着很多的 DOM 操作,编码复杂且不便于维护;而重新渲染虽然省事,但是导致一些性能、焦点消失问题(具体可以看这篇博客介绍</a>)。 因为习惯了 MVVM ...
  • 你必须知道495个C语言问题(PDF)

    热门讨论 2009-09-15 10:25:47
    5.8 但是如果NULL 改变了, 比如在使用非零内部空指针机器 上, 难道用NULL (而不是0) 不是更好吗? . . . . . . . . . . . . . 24 5.9 用预定义宏#define Nullptr(type) (type *)0 帮助创建正确类型 空指针。...
  • 首先是操作系统名字改变了,原因在于虽然我们试验性 OS从前辈们那里借鉴了很多东西,但其各个部分设计(比如文件系统和内存管理)往往有其独特之处,所以我将原先 Tinix(本意为 TryMinix)改成了新名字...
  • 首先是操作系统名字改变了,原因在于虽然我们试验性 OS从前辈们那里借鉴了很多东西,但其各个部分设计(比如文件系统和内存管理)往往有其独特之处,所以我将原先 Tinix(本意为 TryMinix)改成了新名字...
  • 真的很对不起支持我的各位同胞们,经过一个小时的测试修改,终于完成了基本的测试修改工作,我以后还继续努力的,希望各位继续支持我的前进。 2013.6.5更新内容: 新增了图片浏览模块,用户评论,浏览 数据库改变...
  • 已出版部著作和译著,包括《程序设计语言基础》(译著,1990),《Mathematica数学软件系统应用与程序设计》(1994),《从问题到程序——程序设计与C语言引论》(1999) [同作者作品] 计算机基础教程(上下)...
  • 已出版部著作和译著,包括《程序设计语言基础》(译著,1990),《Mathematica数学软件系统应用与程序设计》(1994),《从问题到程序——程序设计与C语言引论》(1999) [同作者作品] 计算机基础教程(上下)...
  • C++程序设计语言(特别版)--源代码

    热门讨论 2012-04-23 07:33:51
    已出版部著作和译著,包括《程序设计语言基础》(译著,1990),《Mathematica数学软件系统应用与程序设计》(1994),《从问题到程序——程序设计与C语言引论》(1999) [同作者作品] 计算机基础教程(上下)...
  • CruiseYoung提供带有详细书签电子书籍目录 ... Oracle Database 9i/10g/11g编程艺术:深入数据库体系结构:第...例如11g引入dbms_parallel_execute包来帮助自动实现原来需要人工实现并行化,以及引入PSQ来控制并行度,...
  • 人工智能全部课件和作业题

    热门讨论 2013-01-11 22:00:10
    说实话,在老师快讲完第三章之前我还一直坐在靠后位置看不清PPT,后来觉得还是要认真听讲,于是每次都是占前两排座位,当然这种做法事后证明也是对,看来有时候一念之差能改变很多。 针对这门课内容没有...
  • 学习Oracle时,很多书和资料都很有参考价值,特别是Oracle文档,更是全面地提供了我们想了解信息。但是文档中没有实战用例,没有告诉我们哪些可行或者哪些不可行,什么情况下可行或者什么情况下不可行,为什么可行...
  • 让默认就可以了,但是超频玩者是肯定不会放过任何可以提高性能的东西的,所以如果你想在这里让你电脑提升一点性能话,就必须慢慢试验,选择一个适当参数才能让你计算机达到性能和稳定最佳状态!...
  • VB课程设计俄罗斯方块

    热门讨论 2011-02-25 10:46:55
    某些与坠落玩具碎片和它们形状有关的东西,使得哪怕新手也会很自然地企图把它们排列起来,并加以适当组合,就好似《俄罗斯方块》触动了我们某些内在感官,使得哪怕是我们当中最杂乱无章人也要把事情整理妥当...
  • 为了训练一个管理人员获得熟练技能,要求他提交论文或报告,详细阐述政府法令、重大事件、自然灾害、消费者兴趣的改变、未来变化趋势等因素对公司发展可能产生影响。即使他在这一方面做得象一个行业发言人一样...
  • 转来备用,以后慢慢学

    2010-05-21 14:14:33
    在动作调板中单击右上角三角形按钮,从弹出菜单中选择载入动作,进入PhotoshopGoodiesActions目录下,其下有按钮、规格、命令、图像效果,文字效果、纹理、帧六个动作集,包含了很多实用的东西哟!另外,在该...
  • A: 预设状态, cFos/cFosSpeed 都是 Ping 德国 cFos (不确定, 得 tracert 查查看), 但是外国往往必须经过很多 router 转接, 所以笔者用 ping_dest= 这个命令 (cfos.ini or cfosspeed.ini) 去改变 Ping 位置, 这个...
  • 经验丰富你一定第一时间意识这样做法导致很多的问题。最大问题就是这样做很慢,因为即使一个小小状态变更都要重新构造整棵 DOM,性价比太低;而且这样做话,<code>input和...
  • flash shiti

    2014-03-14 10:32:41
    11. 全等(===)运算符和相同运算符基本相似,但是它们有一个重要区别 □ A. 全等(===)运算符执行数据类型转换 □ B. 全等(===)运算符不执行数据类型转换 □ C. 全等(===)运算符永远返回...

空空如也

空空如也

1 2 3
收藏数 41
精华内容 16
关键字:

原来时间真的会改变很多东西