为什么 Python 不是 lexical scoping?
这似乎背离了现代程序设计语言的一般设计思路。
比如
<span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">def</span> <span class="nf">inner</span><span class="p">():</span> <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3</span> <span class="k">print</span> <span class="n">inner</span><span class="p">()</span>
回复内容:
这段代码是lexical scoping,静态作用域是指我们可以根据代码文本的位置,确定变量的存在区域。按照python的LEGB(Local,Enclosing,Global,Built-in)规则,当调用inner()时,x实际上是在foo的scope中找到的。inner之所能够访问foo中的x,是因为inner is inside the text of foo,这正是lexical的含义。

Bash是Dynamic Scoping的
<span class="nv">x</span><span class="o">=</span><span class="m">1</span> <span class="k">function</span> g <span class="o">()</span> <span class="o">{</span> <span class="nb">echo</span> <span class="nv">$x</span> <span class="p">;</span> <span class="nv">x</span><span class="o">=</span><span class="m">2</span> <span class="p">;</span> <span class="o">}</span> <span class="k">function</span> f <span class="o">()</span> <span class="o">{</span> <span class="nb">local </span><span class="nv">x</span><span class="o">=</span><span class="m">3</span> <span class="p">;</span> g <span class="p">;</span> <span class="o">}</span> f <span class="c">#f中的g执行时打印出的x是3而不是1</span> <span class="nb">echo</span> <span class="nv">$x</span> <span class="c">#这时打印出的x是1</span>
<span class="k">let</span> <span class="n">foo</span> <span class="bp">()</span> <span class="o">=</span> <span class="k">let</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">in</span> <span class="k">let</span> <span class="n">inner</span> <span class="bp">()</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">in</span> <span class="k">let</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3</span> <span class="k">in</span> <span class="n">print</span> <span class="o">(</span><span class="n">inner</span> <span class="bp">()</span><span class="o">)</span>
这和scoping没有关系。
C++的lambda就可以选择capture by copy或者capture by reference. 根据之前阅读Python源码的经验(如果记错请指正),在题主的例子里面,这个inner是一个闭包。闭包在Python里面的实现方式是保存一个通往外部namespace的指针(可以理解成一个dictionary)。
楼主可以参看这个例子
<span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> <span class="k">def</span> <span class="nf">inner</span><span class="p">():</span> <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">print</span> <span class="n">inner</span><span class="p">()</span> <span class="c"># output 2</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">2</span> <span class="k">print</span> <span class="n">inner</span><span class="p">()</span> <span class="c"># output 3</span>
这分明就是lexical scoping嘛,譬如说等价的C#代码
<span class="k">void</span> <span class="nf">Foo</span><span class="p">()</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">x</span><span class="p">=</span><span class="m">1</span><span class="p">;</span> <span class="n">Func</span><span class="p"><</span><span class="kt">int</span><span class="p">></span> <span class="n">inner</span> <span class="p">=</span> <span class="p">()=></span><span class="n">x</span><span class="p">+</span><span class="m">1</span><span class="p">;</span> <span class="n">x</span><span class="p">=</span><span class="m">3</span><span class="p">;</span> <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">inner</span><span class="p">());</span> <span class="p">}</span>
第一个例子结果都是一样的,因为变量绑定的是引用而不是值。第二个例子:
<span class="k">function</span> <span class="nf">foo</span><span class="p">()</span> <span class="k">function</span> <span class="nf">inner</span><span class="p">()</span> <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">end</span> <span class="kd">local</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3</span> <span class="nb">print</span><span class="p">(</span><span class="n">inner</span><span class="p">())</span> <span class="k">end</span> <span class="n">foo</span><span class="p">()</span>
<span class="p">(</span><span class="kd">function</span> <span class="nx">foo</span><span class="p">()</span> <span class="p">{</span> <span class="kd">function</span> <span class="nx">inner</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">x</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">inner</span><span class="p">());</span> <span class="p">})();</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">():</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">def</span> <span class="nf">inner</span><span class="p">():</span> <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3</span> <span class="k">print</span> <span class="n">inner</span><span class="p">()</span> foo() # 输出4
输出感觉当前 x 走的 這個問題很好回答:x是inner函數的環境變量,所以在inner的定義中出現的x其實就是對定義外面的,也就是inner的環境變量的一個引用而已。
函數只有在被調用的時候才會執行,你前面將置為1,後面又改為3,不過是改變了x的引用值而已,相當於給x重新賦值。然後執行inner函數,使用x所對應的值為3,因此答案就是4了。

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

L'utilisation de return en langage C est la suivante : 1. Pour les fonctions dont le type de valeur de retour est void, vous pouvez utiliser l'instruction return pour terminer l'exécution de la fonction plus tôt. 2. Pour les fonctions dont le type de valeur de retour n'est pas void, la fonction de ; l'instruction return sert à terminer l'exécution de la fonction.Le résultat est renvoyé à l'appelant ;3. Terminer l'exécution de la fonction plus tôt que prévu.À l'intérieur de la fonction, nous pouvons utiliser l'instruction return pour terminer l'exécution de la fonction plus tôt. si la fonction ne renvoie pas de valeur.

Code source : publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}finally{x=3;}}}# Sortie La sortie du code ci-dessus peut simplement conclure : return est exécuté avant finalement. Jetons un coup d'œil à ce qui se passe au niveau du bytecode. Ce qui suit intercepte une partie du bytecode de la méthode case1 et compare le code source pour annoter la signification de chaque instruction dans

Le sucre de syntaxe de configuration de Vue3.2 est un sucre de syntaxe au moment de la compilation qui utilise l'API combinée dans un composant de fichier unique (SFC) pour résoudre la configuration lourde de Vue3.0. Les variables, fonctions et contenus déclarés introduits par l'importation sont exposés via. return, afin qu'ils puissent être utilisés dans Vue3.0. Problèmes d'utilisation 1. Il n'est pas nécessaire de renvoyer les variables, fonctions et contenus déclarés introduits par import lors de l'utilisation. Vous pouvez utiliser du sucre syntaxique //importer le contenu introduit import{getToday. }from'./utils'//variable constmsg='Bonjour !'//function func

L'utilisation de return en JavaScript nécessite des exemples de code spécifiques. En JavaScript, l'instruction return est utilisée pour spécifier la valeur renvoyée par une fonction. Non seulement il peut être utilisé pour terminer l’exécution d’une fonction, mais il peut également renvoyer une valeur à l’endroit où la fonction a été appelée. L'instruction return a les utilisations courantes suivantes : Renvoyer une valeur L'instruction return peut être utilisée pour renvoyer une valeur à l'endroit où la fonction est appelée. Voici un exemple simple : functionadd(a,b){

Les fonctions JavaScript fournissent deux interfaces pour interagir avec le monde extérieur. Les paramètres servent d'entrée pour recevoir des informations externes ; la valeur de retour sert de sortie pour renvoyer les résultats de l'opération vers le monde extérieur. L'article suivant vous amènera à comprendre la valeur de retour de la fonction JavaScript et à analyser brièvement l'utilisation de l'instruction return. J'espère qu'elle vous sera utile !

Comment utiliser return en JavaScript nécessite des exemples de code spécifiques. En JavaScript, return est un mot-clé très important. Il est généralement utilisé pour renvoyer une valeur dans une fonction ou terminer l'exécution d'une fonction. L'instruction return est utilisée pour renvoyer une valeur à l'appelant de la fonction et terminer l'exécution de la fonction. L'instruction return peut être utilisée n'importe où dans une fonction et peut renvoyer n'importe quel type de données JavaScript, y compris des nombres, des chaînes, des booléens,

L'utilisation de la valeur de retour Python est que lorsque la fonction exécute l'instruction return, l'exécution s'arrêtera immédiatement et la valeur spécifiée sera renvoyée à l'endroit où la fonction a été appelée. Utilisation détaillée : 1. Renvoie une seule valeur ; 2. Renvoie plusieurs valeurs ; 3. Renvoie une valeur nulle 4. Terminez l'exécution de la fonction plus tôt.

La touche d'impression d'écran se trouve sur les touches fléchées du clavier, avec les mots "prtsc sysrq" dessus, et est située à droite de f12. S'il n'y a pas de bouton avec le mot « prtsc sysrq », vous pouvez trouver « fn » et « insert (prt sc) », cliquez d'abord sur « fn », puis cliquez sur « insert (PRT sc) » pour réaliser la fonction de capture d'écran d'impression. .
