Understanding closures and decorators in python
The closure in python is defined (interpreted) expressively as: If in an inner function, a variable in the outer scope (but not in the global scope) is referenced, then the inner function is considered closure.
The following instructions are mainly for python2.7, there may be differences in other versions.
Maybe it’s not easy to understand by looking at the definition directly. Let’s first look at what an internal function is:
def wai_hanshu(canshu_1): def nei_hanshu(canshu_2): # 我在函数内部有定义了一个函数 return canshu_1*canshu_2 return nei_hanshu # 我将内部函数返回出去 a = wai_hanshu(123) # 此时 canshu_1 = 123 print a print a(321) # canshu_2 = 321
I have a function nested inside the function. When I pass a variable to the outer function and assign it to a, we find that a becomes a function object, and I again When this function object passes parameters, it also obtains the return value of the internal function. We know that according to the principle of scope, we cannot access the local scope in the global scope. However, the internal functions are accessed here through a tricky method. .
Let’s continue to look at an example:
def wai_hanshu(): a = [] def nei_hanshu(canshu): a.append(canshu) return a return nei_hanshu a = wai_hanshu() print a(123) print a(321)
It can be seen that the function is located in the external function List a has actually changed. To know why, you must first know what a Python namespace is, and namespaces are the reason for scope performance. Here I will briefly explain.
The main reason for introducing namespaces is to avoid variable conflicts, because there are many modules in python, and there are functions, classes, etc. in the modules, and they all use variables. But it would be too troublesome if you have to be careful not to conflict with other variable names every time. Developers should focus on their own problems, rather than thinking about what variables are used in programs written by others, so Python introduced namespaces. The namespace is divided into module layer, and the module is divided into global scope and local scope. If represented by a diagram:
The namespaces between modules are different, and There are also global scopes and local scopes. Local scopes can also be nested before, so as to ensure that variable names do not conflict. By the way, I would like to add that the name of the namespace can be obtained through the __name__ attribute:
The namespace of the main file is called '__main__', and the namespace of the module is the module name. .
The scope is born because when python is looking for a variable, it will first search in the current namespace. If it is not found in the current namespace, it will search in the upper-level namespace. By analogy, if it is not found in the end, an exception of variable not found will be triggered.
We have always said before: the global scope cannot access the local scope, but the local scope can access the global scope for this reason. And when I create a variable in the local scope with the same name as the outside, when python is looking for this variable, it will first look for it in the current scope. If it is found, it will not continue to look for it one level higher.
In early Python versions, local scopes could not access other local scopes, but could only access global ones. However, in current versions, they are searched one level up in order, so I will mention it here.
Because of this feature, we can access the variables in the external function in the internal function, which is the so-called closure.
Note: It is necessary to distinguish between objects here, for example:
def wai_hanshu(): a = [] def nei_hanshu(canshu): a.append(canshu) return a return nei_hanshu a = wai_hanshu() # 我创建了一个对象 b = wai_hanshu() # 我又创建了一个对象 print a print b print a(123) print b(321)
Here , although we all operate variables in wai_hanshu, a and b are completely two objects, and the memory spaces where they are located are also different, so the data inside are also independent. Be careful not to mix things up.
Decorator
In fact, the decorator takes a few more steps based on the closure. Look at the code:
def zsq(func): # 装饰函数 def nei(): print '我在传入的函数执行之前做一些操作' func() # 执行函数 print '我在目标函数执行后再做一些事情' return nei def login(): # 被装饰函数 print '我进行了登录功能' login = zsq(login) # 我将被装饰的函数传入装饰函数中,并覆盖了原函数的入口 login() # 此时执行的就是被装饰后的函数了
在看这段代码的时候,要知道几件事:
1.函数的参数传递的其实是引用,而不是值。
2.函数名也是一个变量,所以可以重新赋值。
3.赋值操作的时候,先执行等号右边的。
只有明白了上面这些事之后,再结合一下代码,应该就能明白什么是装饰器了。所谓装饰器就是在闭包的基础上传递了一个函数,然后覆盖原来函数的执行入口,以后调用这个函数的时候,就可以额外实现一些功能了。装饰器的存在主要是为了不修改原函数的代码,也不修改其他调用这个函数的代码,就能实现功能的拓展。
而python觉得让你每次都进行重命名操作实在太不方便,于是就给出了一个便利的写法:
def zsq(func): def nei(): print '我在传入的函数执行之前做一些操作' func() # 执行函数 print '我在目标函数执行后再做一些事情' return nei @zsq # 自动将其下面的函数作为参数传到装饰函数中去 def login(): print '我进行了登录功能' login()
这些小便利也叫做python的语法糖,你可能在很多地方见过这个说法。
带参数的装饰器:
def zsq(a): print '我是装饰器的参数', a def nei(func): print '我在传入的函数执行之前做一些操作' func() # 执行函数 print '我在目标函数执行后再做一些事情' return nei @zsq('123') def login(): print '我进行了登录功能'
相当于: login = zsq(123)(login) ,所以在这里没有调用就执行了。
装饰器的嵌套:
这里就不完整写个例子了:
@deco1(deco_arg) @deco2 def func(): pass
相当于: func = deco1(deco_arg)(deco2(func))
也就是从上到下的嵌套了。
关于闭包和装饰器就先讲到这里,以后有需要再补充。
以上这篇深入Understanding closures and decorators in python就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持PHP中文网。
更多Understanding closures and decorators in python相关文章请关注PHP中文网!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

This tutorial demonstrates how to use Python to process the statistical concept of Zipf's law and demonstrates the efficiency of Python's reading and sorting large text files when processing the law. You may be wondering what the term Zipf distribution means. To understand this term, we first need to define Zipf's law. Don't worry, I'll try to simplify the instructions. Zipf's Law Zipf's law simply means: in a large natural language corpus, the most frequently occurring words appear about twice as frequently as the second frequent words, three times as the third frequent words, four times as the fourth frequent words, and so on. Let's look at an example. If you look at the Brown corpus in American English, you will notice that the most frequent word is "th

This article explains how to use Beautiful Soup, a Python library, to parse HTML. It details common methods like find(), find_all(), select(), and get_text() for data extraction, handling of diverse HTML structures and errors, and alternatives (Sel

Python's statistics module provides powerful data statistical analysis capabilities to help us quickly understand the overall characteristics of data, such as biostatistics and business analysis. Instead of looking at data points one by one, just look at statistics such as mean or variance to discover trends and features in the original data that may be ignored, and compare large datasets more easily and effectively. This tutorial will explain how to calculate the mean and measure the degree of dispersion of the dataset. Unless otherwise stated, all functions in this module support the calculation of the mean() function instead of simply summing the average. Floating point numbers can also be used. import random import statistics from fracti

This article compares TensorFlow and PyTorch for deep learning. It details the steps involved: data preparation, model building, training, evaluation, and deployment. Key differences between the frameworks, particularly regarding computational grap

Serialization and deserialization of Python objects are key aspects of any non-trivial program. If you save something to a Python file, you do object serialization and deserialization if you read the configuration file, or if you respond to an HTTP request. In a sense, serialization and deserialization are the most boring things in the world. Who cares about all these formats and protocols? You want to persist or stream some Python objects and retrieve them in full at a later time. This is a great way to see the world on a conceptual level. However, on a practical level, the serialization scheme, format or protocol you choose may determine the speed, security, freedom of maintenance status, and other aspects of the program

The article discusses popular Python libraries like NumPy, Pandas, Matplotlib, Scikit-learn, TensorFlow, Django, Flask, and Requests, detailing their uses in scientific computing, data analysis, visualization, machine learning, web development, and H

This article guides Python developers on building command-line interfaces (CLIs). It details using libraries like typer, click, and argparse, emphasizing input/output handling, and promoting user-friendly design patterns for improved CLI usability.

This tutorial builds upon the previous introduction to Beautiful Soup, focusing on DOM manipulation beyond simple tree navigation. We'll explore efficient search methods and techniques for modifying HTML structure. One common DOM search method is ex
