Maison >développement back-end >Tutoriel Python >Analyse complète de la portée des variables en Python à partir des variables locales et des variables globales
Qu'il s'agisse de programmation orientée objet basée sur les classes ou de définition de variables au sein d'une simple fonction, la portée des variables est toujours un lien qui doit être compris et maîtrisé dans l'apprentissage de Python. Commençons par une analyse complète du démarrage de Python. avec des variables locales et des variables globales. Pour la portée des variables, les amis qui en ont besoin peuvent se référer à
Comprendre les variables globales et les variables locales
1 Si le nom de la variable est défini. La fonction apparaît pour la première fois, et avant le symbole =, elle peut être considérée comme définie comme une variable locale. Dans ce cas, que le nom de la variable soit utilisé ou non dans la variable globale, la variable locale est utilisée dans la fonction. Par exemple :
num = 100 def func(): num = 123 print num func()
Le résultat de sortie est 123. Expliquez que le nom de variable num défini dans la fonction est une variable locale et couvre la variable globale. Autre exemple :
num = 100 def func(): num += 100 print num func()
Le résultat de sortie est : UnboundLocalError : variable locale 'num' référencée avant l'affectation. Message d'erreur : la variable locale num est appliquée avant l'affectation. En d’autres termes, la variable est mal utilisée sans être définie. Cela prouve une fois de plus que ce qui est défini ici est une variable locale et non une variable globale.
2. Si le nom de la variable à l'intérieur de la fonction apparaît pour la première fois, apparaît après le symbole = et a déjà été défini comme variable globale, la variable globale sera référencée ici. Par exemple :
num = 100 def func(): x = num + 100 print x func()
Le résultat de sortie est 200. Si le nom de la variable num n'a pas été défini auparavant comme variable globale, un message d'erreur apparaîtra : La variable n'est pas définie. Par exemple :
def func(): x = num + 100 print x func()
Le résultat de sortie est : NameError : le nom global 'num' n'est pas défini.
3. Lorsqu'une variable est utilisée dans une fonction, si le nom de la variable a à la fois des variables globales et des variables locales, la variable locale sera utilisée par défaut. Par exemple :
num = 100 def func(): num = 200 x = num + 100 prinx x func()
Le résultat de sortie est 300.
4. Lorsque vous définissez une variable comme variable globale dans une fonction, vous devez utiliser le mot-clé global. Par exemple :
num = 100 def func(): global num num = 200 print num func() print num
Les résultats de sortie sont respectivement 200 et 200. Cela montre que le nom de la variable num dans la fonction est défini comme une variable globale et se voit attribuer une valeur de 200. Autre exemple :
num = 100 def func(): global num num = 200 num += 100 print num func() print num
Les résultats de sortie sont respectivement 300 et 300.
Sur la base des résultats ci-dessus des scénarios d'application de variables globales et de variables locales, j'ai essayé de faire une analyse sur la première moitié du code d'enseignement dans les champs de saisie (commentaires sur la partie chinoise) :
# calculator with all buttons import simplegui # intialize globals store = 0 operand = 0
Grâce au module simplegui, il peut être exploité sans erreur sur http://www.codeskulptor.org/. Cependant, ce module ne peut pas être utilisé directement dans l'environnement python et le package SimpleGUICS2Pygame doit être installé au préalable.
# event handlers for calculator with a store and operand def output(): """prints contents of store and operand""" print "Store = ", store print "Operand = ", operand print ""
Le magasin et l'opérande des variables globales sont directement utilisés dans la fonction définie output(). Vous pouvez vous référer au point 2.
def swap(): """ swap contents of store and operand""" global store, operand store, operand = operand, store output()
Dans la fonction swap() définie, les variables globales de magasin et d'opérande sont d'abord définies. Si vous ne le faites pas, un message d'erreur apparaîtra indiquant qu'il est utilisé sans attribuer de valeur. Vous pouvez vous référer au point 1. En même temps, peut-on comprendre cela de cette façon : dans la fonction swap(), lorsqu'il n'y a pas de mot-clé global, store et operand sont des variables locales par défaut, et il est faux d'utiliser la partie à droite de = sans affectation. Vous pouvez vous référer au point 3.
def add(): """ add operand to store""" global store store = store + operand output()
Ici, j'ai rencontré le premier problème depuis les deux semaines d'études : c'est pourquoi la fonction add() définit uniquement store comme une variable globale et ne définit pas l'opérande de la même manière. Maintenant combiné avec le point 1, c'est parce que stocker en tant que variable locale n'a pas reçu de valeur à l'avance et ne peut pas être utilisé directement, alors que l'opérande peut être utilisé en appelant directement la variable globale précédemment définie.
Portée variable
La portée variable est un endroit facile pour tomber dans un piège en Python.
Python a un total de 4 portées, qui sont :
Portée locale L (Local)
E (Enclosing) dans une fonction en dehors de la fonction de fermeture
G Portée globale (Globale)
B (Intégré) La portée intégrée
est recherchée selon les règles de L ---> E ---> il sera recherché. Si vous recherchez des pièces locales en dehors de la zone locale (telles que des fermetures), si vous ne les retrouvez pas, vous accéderez à la recherche globale, puis à celles intégrées.
Sauf def/class/lambda en Python, d'autres tels que : if/elif/else/ try/sauf for/while ne peuvent pas changer sa portée. Les variables définies en leur sein sont toujours accessibles de l'extérieur.
>>> if True: ... a = 'I am A' ... >>> a 'I am A'
La variable a définie dans le langage if est toujours accessible de l'extérieur.
Mais veuillez noter que si if est enveloppé par def/class/lambda et attribué en interne, il devient la portée locale de cette fonction/classe/lambda.
L'affectation dans def/class/lambda devient sa portée locale. La portée locale couvrira la portée globale mais n'affectera pas la portée globale.
g = 1 #全局的 def fun(): g = 2 #局部的 return g print fun() # 结果为2 print g # 结果为1
Mais sachez que parfois vous souhaitez faire référence à des variables globales à l'intérieur d'une fonction, et des erreurs se produiront si vous ne parvenez pas à le faire. Par exemple :
#file1.py var = 1 def fun(): print var var = 200 print fun() #file2.py var = 1 def fun(): var = var + 1 return var print fun()
Les deux fonctions. signalera une UnboundLocalError : variable locale 'var' référencée avant l'affectation
Erreur lorsqu'elle est référencée avant l'affectation ! Pourquoi? Parce qu'à l'intérieur de la fonction, l'interpréteur détecte que var a été réaffecté, donc var devient une variable locale, mais si vous souhaitez utiliser var avant qu'elle ne soit affectée, cette erreur se produira. La solution consiste à ajouter une variable globale à l'intérieur de la fonction, mais la variable globale sera également modifiée après l'exécution de la fonction.
闭包Closure
闭包的定义:如果在一个内部函数里,对在外部函数内(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)
函数嵌套/闭包中的作用域:
a = 1 def external(): global a a = 200 print a b = 100 def internal(): # nonlocal b print b b = 200 return b internal() print b print external()
一样会报错- 引用在赋值之前,Python3有个关键字nonlocal可以解决这个问题,但在Python2中还是不要尝试修改闭包中的变量。 关于闭包中还有一个坑:
from functools import wraps def wrapper(log): def external(F): @wraps(F) def internal(**kw): if False: log = 'modified' print log return internal return external @wrapper('first') def abc(): pass print abc()
也会出现 引用在赋值之前 的错误,原因是解释器探测到了 if False 中的重新赋值,所以不会去闭包的外部函数(Enclosing)中找变量,但 if Flase 不成立没有执行,所以便会出现此错误。除非你还需要else: log='var' 或者 if True 但这样添加逻辑语句就没了意义,所以尽量不要修改闭包中的变量。
好像用常规的方法无法让闭包实现计数器的功能,因为在内部进行 count +=1 便会出现 引用在赋值之前 的错误,解决办法:(或Py3环境下的 nonlocal 关键字)
def counter(start): count =[start] def internal(): count[0] += 1 return count[0] return internal count = counter(0) for n in range(10): print count() # 1,2,3,4,5,6,7,8,9,10 count = counter(0) print count() # 1
由于 list 具有可变性,而字符串是不可变类型。
locals() 和 globals()
globals()
global 和 globals() 是不同的,global 是关键字用来声明一个局部变量为全局变量。globals() 和 locals() 提供了基于字典的访问全局和局部变量的方式
比如:如果函数1内需要定义一个局部变量,名字另一个函数2相同,但又要在函数1内引用这个函数2。
def var(): pass def f2(): var = 'Just a String' f1 = globals()['var'] print var return type(f1) print f2() # Just a String # <type 'function'>
locals()
如果你使用过Python的Web框架,那么你一定经历过需要把一个视图函数内很多的局部变量传递给模板引擎,然后作用在HTML上。虽然你可以有一些更聪明的做法,还你是仍想一次传递很多变量。先不用了解这些语法是怎么来的,用做什么,只需要大致了解locals()是什么。
可以看到,locals()把局部变量都给打包一起扔去了。
@app.route('/') def view(): user = User.query.all() article = Article.query.all() ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr) s = 'Just a String' return render_template('index.html', user=user, article = article, ip=ip, s=s) #或者 return render_template('index.html', **locals())
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!