search
HomeBackend DevelopmentPython TutorialIn-depth study of python decorators_python

In-depth study of python decorators_python

Apr 08, 2018 am 11:11 AM
pythonstudy

This article mainly focuses on in-depth study of python decorator related information. What is a decorator? The principles followed by decorators have certain reference value. Interested friends can refer to

What is a decorator

in our software product upgrade Sometimes, we often need to add new functions to each function. In our software products, the same function may be called hundreds of times. This situation is very common. If we modify it one by one, our programmers will Why don't you just hang up (someone said, you are stupid, just modify the function definition! Classmate, please wake up, what if the newly added function will modify the parameters or return value?). At this time, it’s time for our decorator to show its magic. Decorators can achieve the function of adding new functions to the function without changing the calling form of the original function (that is, the transparent processing of the function). How to implement it, as well as the implementation principle, will be explained in detail below.

Principles followed by decorators

Decorators, as the name suggests, play the role of decoration. Since it is decoration, the decorated object is whatever it is. It cannot be There is not the slightest change. Here, when we write a decorator, we must grasp the iron law that the source code of the modified function cannot be modified. How to follow this iron law, we still need to make some preparations. We must first understand three concepts, as follows:

The function name is "variable"

In Python, the function name is actually like a function pointer in C language, which represents our function address. Only when the interpreter obtains this address will it execute this piece of memory. code. Therefore, in essence, the function name is no different from different variables, except that the function name and the memory pointed to by the ordinary variable are used in different ways. These are determined by the mechanism of the underlying interpreter. For programmers, , are both transparent, so we can think that there is no difference between the two.

Higher-order function

What is a higher-order function is actually very simple, just grasp two principles:

  • Formal parameters have function names

  • Return values ​​have function names

As long as one of these two principles is met , it can be called a higher-order function. Looking back, the function name we mentioned above appears here. If you think about it carefully, don't we treat it as an actual parameter here?

Nested functionnumber

What is a nested function is actually very simple. Just grasp one principle:

  • Define another function in the function body of a function

What needs to be emphasized here Yes, when a function is defined, the function body will not be executed, just like when a variable is defined, the contents of the variable will not be read. This is crucial and very helpful for us to understand the principle of decorator implementation.

How to write a decorator

With the above foreshadowing, let’s explain in detail how to write a decorator now, so that it will be much easier to understand.

The essence of decorator

In fact, a decorator is essentially a function, which also has a function name, parameters and return value. But in python, we use "@auth" to represent it.

@auth    # 其等价于:func = auth(func)
def func():
  print("func called")

This example is how to modify the format of the func function in python. Of course, we have not implemented our decorator function yet. What we need to pay attention to is the content written in the comments. We can see that:

  • The decorator function is actually a higher-order function (both parameters and return values ​​are function names).

  • "auth(func)" is calling our decorator function, that is, the function body of the decorator function will be executed. Be sure to remember this.

Design ideas

Since the decorator is a function, it also has the equivalence relationship introduced above , then we can design our decorator like this:

  • Define a new function in the function body of our decorator, and call the modified function in this newly defined function Functions, meanwhile, add new functionality in the context of the modified function. Finally, use the return value of the decorator function to return the function name of our newly defined function.

  • It can be known that the return value func in "func = auth(func)" represents the function name of the newly defined function in the decorator.

I have made a lot of preparations before, just to reveal the implementation mechanism of the decorator. In fact, it is nothing, it is very simple:

  • 装饰器机制改变了被修饰函数的函数名表示的地址数据。说白了就是,被修饰前,函数名代表的是A内存块;被修饰后,函数名代表的是B内存块;只不过,在执行B内存块时,会调用A内存块罢了。B内存块中的代码就是我们新加的功能。而这种机制的实现,使用了“高阶函数”和“嵌套函数”的机制。

  • 最终的效果就是,但在调用被修饰过的函数时,其实调用的不是原来的内存块,而是修饰器新申请的内存块。

第一步:设计装饰器函数

装饰器函数定义跟普通函数定义没什么区别,关键是函数体怎么写的问题。这里,为了便于理解,先用无参数的装饰器函数说明。

#装饰器函数定义格式
def deco(func):
  '''函数体...'''
return func

这里说的无参数,指的是没有除了“func”之外的参数
难点是函数体的编写,下面的示例先告诉你为什么要有第二步:

#使用语法糖@来装饰函数,相当于“myfunc = deco(myfunc)”
def deco(func):
  print("before myfunc() called.")
  func()
  print("after myfunc() called.")
  return func
 
@deco
def myfunc():
  print("myfunc() called.")
 
myfunc()
myfunc()
 
#output:
before myfunc() called.
myfunc() called.
after myfunc() called.
myfunc() called.
myfunc() called.

由输出结果可以看出,我们的装饰器并没有生效。别跟我说装饰器只生效了一次,那是大家忽略了“@deco”的等效机制。解释到“@deco”时,会解释成“myfunc = deco(myfunc)”。注意了,前面我提到了,这里其实在调用deco函数的,因此,deco的函数体会被执行。所以output的前三行并不是调用myfunc函数时产生的效果,那有怎能说装饰器生效了一次呢?第二步就是解决装饰器没生效的问题的。

第二步:包装被修饰函数

#基本格式
def deco(func):
  def _deco()
    #新增功能
    #...
    #...
    func() #别修饰函数调用
  return_deco

 下面给出个示例:

#使用内嵌包装函数来确保每次新函数都被调用,
#内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象
 
def deco(func):
  def _deco():
    print("before myfunc() called.")
    func()
    print("after myfunc() called.")
    # 不需要返回func,实际上应返回原函数的返回值
  return _deco
 
@deco
def myfunc():
  print("myfunc() called.")
  return 'ok'
 
myfunc()
 
#output:
before myfunc() called.
myfunc() called.
after myfunc() called.

  第三步:被修饰函数参数和返回值透明化处理

当完成了第二步时,其实装饰器已经完成了主要部分,下面就是对被修饰函数的参数和返回值的处理。这样才能真正实现装饰器的铁律。话不多说,直接上代码:

#基本格式
def deco(func):
  def _deco(*args, **kwargs) #参数透明化
    #新增功能
    #...
    #...
    res = func(*args, **kwargs) #别修饰函数调用
    return res #返回值透明化
  return_deco

通过上面的分析知:

参数透明化:当我们在调用被装饰后的函数时,其实调用的时这里的_deco函数。那么,我们就给_deco函数加上可变参数,并把得到的可变参数传递给func函数不就可以了。
返回值透明化:和参数透明化同理,给_deco函数定义返回值,并返回func的返回值就可以了。

透明化处理就是这么简单!至此,我们的装饰器编写完成。给个示例吧:

#对带参数的函数进行装饰,
#内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装函数对象
 
def deco(func):
  def _deco(*agrs, **kwagrs):
    print("before myfunc() called.")
    ret = func(*agrs, **kwagrs)
    print(" after myfunc() called. result: %s" % ret)
    return ret
  return _deco
 
@deco
def myfunc(a, b):
  print(" myfunc(%s,%s) called." % (a, b))
  return a + b
 
print("sum=",myfunc(1, 2))
print("sum=",myfunc(3, 4))
 
#output:
before myfunc() called.
 myfunc(1,2) called.
 after myfunc() called. result: 3
sum= 3
before myfunc() called.
 myfunc(3,4) called.
 after myfunc() called. result: 7
sum= 7

装饰器进阶

带参数装饰器

装饰器即然也是函数,那么我们也可以给其传递参数。我这里说的是:“@auth(auth_type = 'type1')”这中形式哟。先上个代码吧:

#基本格式
def deco(deco_type)
  def _deco(func):
    def __deco(*args, **kwargs) #参数透明化
      #新增功能
      #...
      #...
      print("deco_type:",deco_type) #使用装饰器参数
      res = func(*args, **kwargs) #别修饰函数调用
      return res #返回值透明化
    return __deco
  return_deco

 说白了,就是在原来的装饰器的基础上再在最外层套一个deco函数,并用其来接收装饰器参数。由于是在最外层套了一个函数,那么这个函数的形参的作用范围就是函数体内部,所以里面的函数定义中随便用啦,就这么任性。
那怎么理解解释器的解析过程呢?在这里,只要我们明白一点就好,那就是: “@auth(auth_type = 'type1')”等价于“func = auth(auth_type = 'type1')(func)” 解释器会先翻译“auth(auth_type = 'type1')”,再将其返回值(假设给了_func这个不存在的函数名)当作函数指针,这里的_func函数名代表的是_deco,然后再去执行“func = _func(func)”,而这个func函数名代表的其实就是__deco。

至此,就达到了通过装饰器来传参的目的。给个示例吧:

#示例7: 在示例4的基础上,让装饰器带参数,
#和上一示例相比在外层多了一层包装。
#装饰函数名实际上应更有意义些
 
def deco(deco_type):
  def _deco(func):
    def __deco(*args, **kwagrs):
      print("before %s called [%s]." % (func.__name__, deco_type))
      func(*args, **kwagrs)
      print(" after %s called [%s]." % (func.__name__, deco_type))
    return __deco
  return _deco
 
@deco("mymodule")
def myfunc():
  print(" myfunc() called.")
 
@deco("module2")
def myfunc2():
  print(" myfunc2() called.")
 
myfunc()
myfunc2()
 
#output:
before myfunc called [mymodule].
 myfunc() called.
 after myfunc called [mymodule].
before myfunc2 called [module2].
 myfunc2() called.
 after myfunc2 called [module2].

多重装饰器修饰函数

如果说,我上面说的内容都理解了,那么这个东东,就太简单不过了。不就是把我们的是装饰器当中被修饰的函数,对它进行装饰吗?但我在这里还想说的是,我们换个角度看问题。我们的关注点放在原来的被修饰的函数上,就会发现,NB呀,我可以给它添加若干个功能撒。给个示例吧:

def deco(deco_type):
  def _deco(func):
    def __deco(*args, **kwagrs):
      print("before %s called [%s]." % (func.__name__, deco_type))
      func(*args, **kwagrs)
      print(" after %s called [%s]." % (func.__name__, deco_type))
    return __deco
  return _deco
 
@deco("module1")
@deco("mymodule")
def myfunc():
  print(" myfunc() called.")
 
@deco("module2")
def myfunc2():
  print(" myfunc2() called.")
 
myfunc()
 
#output:
before __deco called [module1].
before myfunc called [mymodule].
 myfunc() called.
 after myfunc called [mymodule].
 after __deco called [module1].

 注意结果哟,@deco("module1"),来修饰的deco("mymdule")的,和我们想的是一样的,完美!

相关推荐:

深度理解Python装饰器的概念和含义

A simple explanation of python decorators

#

The above is the detailed content of In-depth study of python decorators_python. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Python and Time: Making the Most of Your Study TimePython and Time: Making the Most of Your Study TimeApr 14, 2025 am 12:02 AM

To maximize the efficiency of learning Python in a limited time, you can use Python's datetime, time, and schedule modules. 1. The datetime module is used to record and plan learning time. 2. The time module helps to set study and rest time. 3. The schedule module automatically arranges weekly learning tasks.

Python: Games, GUIs, and MorePython: Games, GUIs, and MoreApr 13, 2025 am 12:14 AM

Python excels in gaming and GUI development. 1) Game development uses Pygame, providing drawing, audio and other functions, which are suitable for creating 2D games. 2) GUI development can choose Tkinter or PyQt. Tkinter is simple and easy to use, PyQt has rich functions and is suitable for professional development.

Python vs. C  : Applications and Use Cases ComparedPython vs. C : Applications and Use Cases ComparedApr 12, 2025 am 12:01 AM

Python is suitable for data science, web development and automation tasks, while C is suitable for system programming, game development and embedded systems. Python is known for its simplicity and powerful ecosystem, while C is known for its high performance and underlying control capabilities.

The 2-Hour Python Plan: A Realistic ApproachThe 2-Hour Python Plan: A Realistic ApproachApr 11, 2025 am 12:04 AM

You can learn basic programming concepts and skills of Python within 2 hours. 1. Learn variables and data types, 2. Master control flow (conditional statements and loops), 3. Understand the definition and use of functions, 4. Quickly get started with Python programming through simple examples and code snippets.

Python: Exploring Its Primary ApplicationsPython: Exploring Its Primary ApplicationsApr 10, 2025 am 09:41 AM

Python is widely used in the fields of web development, data science, machine learning, automation and scripting. 1) In web development, Django and Flask frameworks simplify the development process. 2) In the fields of data science and machine learning, NumPy, Pandas, Scikit-learn and TensorFlow libraries provide strong support. 3) In terms of automation and scripting, Python is suitable for tasks such as automated testing and system management.

How Much Python Can You Learn in 2 Hours?How Much Python Can You Learn in 2 Hours?Apr 09, 2025 pm 04:33 PM

You can learn the basics of Python within two hours. 1. Learn variables and data types, 2. Master control structures such as if statements and loops, 3. Understand the definition and use of functions. These will help you start writing simple Python programs.

How to teach computer novice programming basics in project and problem-driven methods within 10 hours?How to teach computer novice programming basics in project and problem-driven methods within 10 hours?Apr 02, 2025 am 07:18 AM

How to teach computer novice programming basics within 10 hours? If you only have 10 hours to teach computer novice some programming knowledge, what would you choose to teach...

How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading?How to avoid being detected by the browser when using Fiddler Everywhere for man-in-the-middle reading?Apr 02, 2025 am 07:15 AM

How to avoid being detected when using FiddlerEverywhere for man-in-the-middle readings When you use FiddlerEverywhere...

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.