精华内容
下载资源
问答
  • 在编程中,如对函数接收类型,有要求,比如: def add(x, y): return x + y if __name__ == '__main__': x = add(2,3) print("x=",x) 我们一看,就知道,这个出现:TypeError。   那么在编程...

    在编程中,如对函数的接收类型,有要求,比如:

    def add(x, y):
        return x + y
    
    if __name__ == '__main__':
        x = add(2,3)
        print("x=",x)

    我们一看,就知道,这个出现:TypeError。

     

    那么在编程时,为了使用接收的参数的正确。我们可以使用python中的装饰器。

    构建一个装饰器:

    def requires_ints(decorated):
        def inner(*args, **kwargs):
            kwarg_values = [i for i in kwargs.values()]
            for arg in list(args) + kwarg_values:
                if not isinstance(arg, int):
                    raise TypeError("参数中存在不是Int类型的:", decorated.__name__)
    
            return decorated(*args, **kwargs)
        
        return inner

    测试方法:

    @requires_ints
    def add(x, y):
        return x + y
    
    
    if __name__ == '__main__':
        # print(help(add))
        x = add(2,3)
        print("x=",x)
    

    输出过程:


     

    完整代码:

    # -*- coding: utf8 -*-
    
    """
    # __author__ = "Tom枫明"
    # HomePage: https://blog.csdn.net/fm345689
    # Python -V: Python 3.6.1
    """
    
    """
    装饰器:判断对应是否为一个Int类型
    """
    
    def requires_ints(decorated):
        def inner(*args, **kwargs):
            kwarg_values = [i for i in kwargs.values()]
            for arg in list(args) + kwarg_values:
                if not isinstance(arg, int):
                    raise TypeError("参数中存在不是Int类型的:", decorated.__name__)
    
            return decorated(*args, **kwargs)
    
        return inner
    
    
    @requires_ints
    def add(x, y):
        return x + y
    
    
    if __name__ == '__main__':
        # print(help(add))
        x = add(2,3.0)
        print("x=",x)
    
    

     

     

    展开全文
  • 其实,python 中的装饰器本质上就是一个函数,这个函数接收其他的函数作为参数,并将其以一个全新的修改后的函数替换它 关于装饰器的知识是python面试中比较常见的,对于装饰器的理解可以看这篇文章:理解Python中的...

    其实,python 中的装饰器本质上就是一个函数,这个函数接收其他的函数作为参数,并将其以一个全新的修改后的函数替换它
    关于装饰器的知识是python面试中比较常见的,对于装饰器的理解可以看这篇文章:理解Python中的装饰器,理解之后,再手写一遍下面的8种装饰器加深理解以后使用就更轻松多了!

    1.最简单的函数

    def myfunc()
    	print "i am a function"
    
    myfunc()
    

    2.初步了解装饰函数的调用结构

    在函数执行前和执行后分别计时,打印函数运行消耗的时间

    import datetime
    import time
    def out(fun):
    	start = datetime.datetime.now()
    	fun()
    	end = datetime.datetime.now()
    	print (end-start)
    	return fun
    def inner():
        time.sleep(1)
        print ("i am inner func")
    
    myfunc = out
    
    myfunc(inner)
    

    3.尝试引用@语法糖来调用装饰函数

    import datetime,time
    def out(func):
        start =datetime.datetime.now()
        func()
        end = datetime.datetime.now()
        print(end-start)
        return func
    
    @out
    def myfunc():
        time.sleep(1)
        print("zhangkun inner")
    

    4.使用内嵌的包装函数

    使用内嵌包装函数来确保每次新函数都被调用,内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象

    import datetime,time
    
    def out(func):
        def inner():
            start = datetime.datetime.now()
            func()
            end = datetime.datetime.now()
            print(end-start)
            print("out and inner")
        return inner
    
    @out
    def myfunc():
        time.sleep(1)
        print("zhangkun")
    
    myfunc()
    

    5.对带参数的函数使用装饰器

    内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象

    import datetime,time
    
    def out(func):
        def inner(*args):
            start = datetime.datetime.now()
            func(*args)
            end = datetime.datetime.now()
            print(end-start)
            print("out and inner")
        return inner
    
    @out
    def myfunc(*args):
        time.sleep(1)
        print("args is{}".format(args))
    
    myfunc("lalalal")
    

    6.给装饰器参数

    和上一示例相比在外层多了一层包装

    #coding:utf-8
    def outermost(*args):
    	def out(func):
    		print ("装饰器参数{}".format(args))
    		def inner(*args):
    			print("innet start")
    			func(*args)
    			print ("inner end")
    		return inner
    	return out
    
    @outermost(666)
    def myfun(*args):
    	print ("试试装饰器和函数都带参数的情况,被装饰的函数参数{}".format(args))
    
    myfun("zhangkun")
    

    7.带类参数的装饰器

    class locker:
        def __init__(self):
            print("locker.__init__() should be not called")
    
        @staticmethod
        def acquire():
            print("locker.acquire() static method be called")
    
        @staticmethod
        def release():
            print("locker.release() static method be called")
    
    def outermost(cls):
        def out(func):
            def inner():
                cls.acquire()
                func()
                cls.release()
            return inner
        return out
    
    @outermost(locker)
    def myfunc():
        print("myfunc called")
    
    myfunc()
    

    8.对一个函数应用多个装饰器

    class mylocker:
        def __init__(self):
            print("mylocker.__init__() called.")
    
        @staticmethod
        def acquire():
            print("mylocker.acquire() called.")
    
        @staticmethod
        def unlock():
            print("  mylocker.unlock() called.")
    
    class lockerex(mylocker):
        @staticmethod
        def acquire():
            print("lockerex.acquire() called.")
    
        @staticmethod
        def unlock():
            print("  lockerex.unlock() called.")
    
    def lockhelper(cls):
        def _deco(func):
            def __deco2(*args, **kwargs):
                print("before %s called." % func.__name__)
                cls.acquire()
                try:
                    return func(*args, **kwargs)
                finally:
                    cls.unlock()
            return __deco2
        return _deco
    
    class example:
        @lockhelper(mylocker)
        @lockhelper(lockerex)
        def myfunc2(self, a, b):
            print(" myfunc2() called.")
            print(a+b)
    
    a = example()
    a.myfunc2(1,2)
    

    9.作为一个类

    虽然装饰器几乎总是可以用函数实现,但是在某些情况下,使用用户自定义的类可能会更好,如果装饰器需要复杂的参数化或者依赖特定状态,那么这种说法往往是对的
    非参数化装饰器用作类的通用模式如下

    class DerocatorAsClass:
        def __init__(self,funcation):
            self.funcation = funcation
    
        def __call__(self, *args, **kwargs):
            # 调用函数之前,做点什么
            result = self.funcation(*args,**kwargs)
            # 在调用之后做点什么并且返回结果
            return result
    
    展开全文
  • func1.py 文件1、执行到@w12、被装饰函数作为装饰器参数 w1(func=f1())3、w1 函数执行有返回值,得用变量接收,变量名为f1 合适"""def w1(func):def inner():print('...验证权限...')func()return ...

    """

    func1.py 文件

    1、执行到@w1

    2、被装饰函数作为装饰器参数 w1(func=f1())

    3、w1 函数执行有返回值,得用变量接收,变量名为f1 合适

    """

    def w1(func):

    def inner():

    print('...验证权限...')

    func()

    return inner

    @w1

    def f1():

    print('f1 called')

    ===================================================

    """

    func2.py 文件

    1、执行到@w1

    2、被装饰函数作为装饰器参数 w1(func=f1())

    3、w1 函数执行有返回值,得用变量接收,变量名为f1 合适

    """

    def w1(func):

    def inner():

    print('...验证权限...')

    func()

    return inner

    @w1

    def f1():

    print('f1 called')

    f1()

    """

    执行f1() 实际执行的是谁?-->是inner() 函数

    为什么?-->步骤3 w1 函数返回值赋值给了f1

    那实际是什么赋值给f1 变量了?-->是inner() 函数

    现在执行f1() 当然执行的是inner() 函数

    在执行inner() 函数的过程中有个func() 这个是什么?-->是w1 函数的参数

    那这个函数实际执行的是谁?-->步骤2 有说明,实际指向的是被装饰的函数f1

    """

    AAffA0nNPuCLAAAAAElFTkSuQmCC

    AAffA0nNPuCLAAAAAElFTkSuQmCC

    展开全文
  • 无参装饰器函数和带参装饰器函数

    千次阅读 2016-10-07 15:41:26
    一、无参装饰器函数 Python的 decorator (装饰器) 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。 使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样...

    一、无参装饰器函数

    Python的 decorator (装饰器) 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数。

    使用 decorator 用Python提供的 @ 语法,这样可以避免手动编写 f = decorate(f) 这样的代码。

    例1:

    #!/usr/bin/env python
    #coding=utf-8
    
    #装饰器函数
    def log(f):
        def fn(n):
            print 'call', f.__name__ + '()'
            return f(n)
        return fn
    
    #阶乘函数
    @log
    def factorial(n):
         return reduce(lambda x,y : x*y, range(1,n+1))
    
    print factorial(5)
    结果:


    对于参数只有一个的函数,@log工作的很好,但是当参数不是一个的函数,调用将报错:

    例2:

    #加法函数
    @log
    def add(x, y):
         return x+y
    
    print add(1+2)
    结果:



    因为add()函数需要传入两个参数,但是@log写死了只含一个参数的返回函数。

    所以要让 @log 自适应任何参数定义的函数,可以利用python的*arg 和 **kw,保证任意个数的参数能正常调用。

    例3:

    #!/usr/bin/env python
    #coding=utf-8
    
    #装饰器函数
    def log(f):
        def fn(*args, **kw):
            print 'call', f.__name__ + '()'
            return f(*args, **kw)
        return fn
    
    #阶乘函数
    @log
    def factorial(n):
        return reduce(lambda x,y : x*y, range(1,n+1))
    
    #加法函数
    @log
    def add(x, y):
         return x+y
    
    print add(1, 2)
    print factorial(5)
    结果:



    二、带参数的装饰器函数

    需求来了:

    如果有的函数非常重要,希望打印出'[INFO] call xxx()...',有的函数不太重要,希望打印出'[DEBUG] call xxx()...',这时,

    log函数本身就需要传入'INFO'或'DEBUG'这样的参数,类似这样:

    @log('DEBUG')
    def my_func():
        pass

    翻译成高阶函数相当于:

    my_func = log('DEBUG')(my_func)

    或者:

    log_decorator = log('DEBUG')
    my_func = log_decorator(my_func)
    又相当于:

    log_decorator = log('DEBUG')
    @log_decorator
    def my_func():
        pass

    估计看明白了。带参数的装饰器函数其实就是在原来的基础上添加外层函数,又返回内层的装饰器函数而已,也是很简单的。


    总结:带参数的log函数首先返回一个decorator函数,再让这个函数接收decorator函数接收my_func并返回函数。

    代码如下:

    def log(prefix):
        def log_decorator(f):
            def wrapper(*args, **kw):
                print '[%s] %s()...' % (prefix, f.__name__)
                return f(*args, **kw)
            return wrapper
        return log_decorator
    
    @log('DEBUG')
    def test():
        pass
    print test()
    结果:



    无参装饰器函数和有参的装饰器函数就基本上告一段落。









    展开全文
  • 题目要求: 代码: 运行结果:
  • 1.题目: 2.代码:
  • 北京今天天儿不错,在家写点... 使用系统内置的warps装饰器能够使被装饰的函数保留他原始的信息, 直观一点就是在你print(func.__name__)的时候这个函数的名字仍然是func而不是new_func. """ @warps def new...
  • 装饰器接收被装饰的函数 def wrapper(*args, **kwargs): # 2. wrapper 接收被装饰函数参数,然后将参数传给被装饰的函数: print(f'wrapper() 接收到位置参数{args}, 关键字参数{kwargs}') start_ti = time....
  • python 类装饰器如何接收request参数

    千次阅读 2018-07-30 10:09:43
    我们在django中想要给类加上装饰器, 又想要用到被装饰函数的request参数 怎么办 ~   我这是用来做权限校验的一个装饰器, 以此为例: class UserAuthentication(object):  def __init__(self, func):  self....
  • 1.题目: 2.代码: 3.结果:
  • 万能参数args:接收的是按照位置传参的值,然后组成一个元组**kwargs:接收的是按照关键字传参的值,然后组成一个字典传参的时候必须先按照位置传,然后是默认参数,然后再按照关键字传递(形参和实参中的都一样)在参数...
  • 1.题目: 2.代码: 补充: isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。 举例:
  • Python高阶函数与装饰器函数 高阶函数 1、可以使用函数对象作为参数的函数 2、或可以将函数作为返回值的函数 3、函数对象:定义好的函数,使用函数名调用(不要加括号) #将函数作为参数的高阶函数,通过传入不同...
  • 题目要求: 代码: 运行结果:
  • 本文主要介绍的是Python高阶函数与装饰器函数的相关内容,分享给大家,下面话不多说了,来一起看看详细的介绍吧高阶函数1、可以使用函数对象作为参数的函数 2、或可以将函数作为返回值的函数 3、函数对象:定义好的...
  • 装饰器接收函数作为参数,添加功能后返回一个新函数函数(类),装饰器既可以通过函数去实现,也可以通过类去实现。 Python中通过 @ 使用装饰器 装饰器模式就是通过实现一个装饰器,在不修改原来函数的情况下就...
  • 本文主要介绍的是Python高阶函数与装饰器函数的相关内容,分享给大家,下面话不多说了,来一起看看详细的介绍吧 高阶函数 1、可以使用函数对象作为参数的函数 2、或可以将函数作为返回值的函数 3、函数对象:定义...
  • 装饰器为@required_types(int,float)确保函数接收到的 每一个参数都是int或者float类型; # 2). 当装饰器为@required_types(list)确保函数接收到的每一个 参数都是list类型; # 3). 当装饰器为@required_...
  • 函数装饰器

    2019-06-07 19:12:00
    对于某个函数,如果希望在不改变函数代码的前提下,为该函数增加额外的功能,那么可以使用装饰器来装饰该函数。...为了让内函数接收任意类型的参数,将内函数的形参定义为(*args, **kwargs)。在函数中首选完成为...
  • 本文主要介绍的是Python高阶函数与装饰器函数的相关内容,分享给大家,下面话不多说了,来一起看看详细的介绍吧高阶函数1、可以使用函数对象作为参数的函数2、或可以将函数作为返回值的函数3、函数对象:定义好的...
  • 高阶函数是在Python中一个非常有用的功能函数,所谓高阶函数就是一个函数可以用来接收另一个函数作为参数,这样的函数叫做高阶函数。 map() map()是 Python 内置的高阶函数,它接收一个函数function 和一个 list,并...
  • 万能参数args:接收的是按照位置传参的值,然后组成一个元组**kwargs:接收的是按照关键字传参的值,然后组成一个字典传参的时候必须先按照位置传,然后是默认参数,然后再按照关键字传递(形参和实参中的都一样)在参数...
  • 写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数函数,它返回一个接收函数的的函数。但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函数...
  • 在了解装饰器的之前一定要先了解函数作为参数传递, 什么是函数内嵌,请参考我之前写的博客函数简介因为在python里面,函数也是对象,也可以作为参数进行传递.python装饰器本质也是一种特殊函数,它接收参数函数对象,...
  • 万能参数 args:接收的是按照位置传参的值,然后组成一个元组 **kwargs:接收的是按照关键字传参的值,然后组成一个字典 传参的时候必须先按照位置传,然后是默认参数,然后再按照关键字传递(形参和实参中...
  • 1.题目: 2.代码: 3.输出: 补充: isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。 举例:
  • 函数接收参数是一个函数名2.函数的返回值是一个函数名以上两者满足任意一个,就是高阶函数装饰器定义本质就是函数,功能是为其他函数添加新功能装饰器的原则1.不修改被装饰函数的源代码(开放封闭原则)2.为被装饰...
  • python 函数装饰器

    2018-04-18 17:47:12
    在学习装饰器的时候,对带参数装饰器有些不太理解 通过例子有了一点想法记录下来,后续遇到问题的时候回顾反思一下吧问题:打印出函数运行的时间,可以传入参数 选择打印s 或者 ms代码:import time def ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 555
精华内容 222
关键字:

装饰器函数接收参数