클래스 기반 객체지향 프로그래밍이든, 간단한 함수 내에서 변수를 정의하든, 변수의 범위는 Python 학습에서 항상 이해하고 숙달해야 하는 연결 고리입니다. Python에서 변수에 대한 포괄적인 분석부터 시작하겠습니다. 지역변수와 전역변수에 대해서는
전역변수와 지역변수 이해하기
1를 참고하세요. 지역 변수로 정의된 것으로 간주됩니다. 이 경우, 전역 변수에서 변수 이름을 사용하는지 여부와 관계없이 함수에서는 로컬 변수를 사용합니다. 예:
num = 100 def func(): num = 123 print num func()
출력 결과는 123입니다. 함수에 정의된 변수명 num은 지역변수이고 전역변수를 포괄한다는 점을 설명한다. 또 다른 예:
num = 100 def func(): num += 100 print num func()
출력 결과는 다음과 같습니다. UnboundLocalError: 할당 전에 지역 변수 'num'이 참조되었습니다. 오류 메시지: 할당 전에 지역 변수 num이 적용되었습니다. 즉, 변수를 정의하지 않고 잘못 사용하고 있는 것입니다. 이는 여기에 정의된 내용이 전역 변수가 아닌 지역 변수임을 다시 한 번 증명합니다.
2. 함수 내부에 변수명이 처음 나타나고, = 기호 뒤에 나타나며, 이전에 전역 변수로 정의된 적이 있다면 여기서는 전역 변수를 참조하게 됩니다. 예:
num = 100 def func(): x = num + 100 print x func()
출력 결과는 200입니다. 변수 이름 num이 이전에 전역 변수로 정의되지 않은 경우 다음과 같은 오류 메시지가 나타납니다. 변수가 정의되지 않았습니다. 예:
def func(): x = num + 100 print x func()
출력 결과는 다음과 같습니다. NameError: 전역 이름 'num'이 정의되지 않았습니다.
3. 함수에서 변수를 사용할 때 변수 이름에 전역 변수와 지역 변수가 모두 있으면 기본적으로 지역 변수가 사용됩니다. 예:
num = 100 def func(): num = 200 x = num + 100 prinx x func()
출력 결과는 300입니다.
4. 함수에서 변수를 전역 변수로 정의할 때는 global 키워드를 사용해야 합니다. 예:
num = 100 def func(): global num num = 200 print num func() print num
출력 결과는 각각 200과 200입니다. 이는 함수의 변수 이름 num이 전역 변수로 정의되어 값 200이 할당되었음을 보여줍니다. 또 다른 예:
num = 100 def func(): global num num = 200 num += 100 print num func() print num
출력 결과는 각각 300과 300입니다.
위의 전역 변수와 지역 변수의 적용 시나리오 결과를 결합하여 입력 필드의 교육 코드 전반부에 대한 분석을 시도했습니다(중국어 부분에 대한 설명):
# calculator with all buttons import simplegui # intialize globals store = 0 operand = 0
simplegui 사용 모듈을 사용하면 http://www.codeskulptor.org/가 올바르게 작동할 수 있습니다. 하지만 이 모듈은 Python 환경에서 직접 사용할 수 없으며 SimpleGUICS2Pygame 패키지를 먼저 설치해야 합니다.
# event handlers for calculator with a store and operand def output(): """prints contents of store and operand""" print "Store = ", store print "Operand = ", operand print ""
전역변수 store와 피연산자는 정의된 함수output()에서 직접 사용됩니다. 2번 항목을 참고하시면 됩니다.
def swap(): """ swap contents of store and operand""" global store, operand store, operand = operand, store output()
정의된 함수 swap()에서는 먼저 store와 Operand의 전역 변수를 정의합니다. 그렇지 않으면 값을 할당하지 않고 사용한다는 오류 메시지가 나타납니다. 1번 항목을 참고하시면 됩니다. 동시에 다음과 같이 이해해도 될까요: swap() 함수에서 global 키워드가 없을 때 store와 피연산자는 기본 지역 변수이고 = 오른쪽 부분을 사용하는 것은 잘못된 것입니다. 할당 없이. 3번 항목을 참고하시면 됩니다.
def add(): """ add operand to store""" global store store = store + operand output()
여기서 2주 과정 학습 이후 첫 번째 문제에 직면했습니다. 이것이 바로 add() 함수가 store를 전역 변수로만 정의하고 피연산자를 같은 방식으로 정의하지 않는 이유입니다. 이제 1번과 합쳐지면 로컬 변수인 store는 미리 값을 할당하지 않아 직접 사용할 수 없는 반면, 피연산자는 앞서 정의한 글로벌 변수를 직접 호출하여 사용할 수 있기 때문이다.
가변 범위
가변 범위(scope)는 파이썬에서 함정에 빠지기 쉬운 곳입니다.
Python에는 총 4개의 범위가 있습니다.
L(로컬) 로컬 범위
E(인클로징) 클로저 함수 외부 함수
G(글로벌) 글로벌 범위
B(내장) 구성 범위
L --> 의 규칙에 따라 검색됩니다. 도착하면 전역 검색으로 이동한 다음 내장 검색으로 이동합니다.
Python의 def/class/lambda를 제외하고 if/elif/else/ try/except for/while과 같은 다른 것들은 범위를 변경할 수 없습니다. 그 안에 정의된 변수는 외부에서 계속 접근할 수 있습니다.
>>> if True: ... a = 'I am A' ... >>> a 'I am A'
if 언어에 정의된 변수 a는 외부에서 여전히 접근 가능합니다.
하지만 def/class/lambda로 래핑되어 내부적으로 할당되면 이 함수/클래스/lambda의 로컬 범위가 된다는 점에 유의해야 합니다.
def/class/lambda 내의 할당은 로컬 범위가 됩니다. 로컬 범위는 전역 범위를 포함하지만 전역 범위에는 영향을 미치지 않습니다.
g = 1 #全局的 def fun(): g = 2 #局部的 return g print fun() # 结果为2 print g # 结果为1
그러나 때로는 함수 내에서 전역 변수를 참조하려는 경우 주의하지 않으면 오류가 발생할 수 있습니다. 예:
#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()
두 함수 모두 UnboundLocalError: local Variable 'var' referenced before 할당이라는 오류를 보고합니다.
과제 전 인용 오류! 왜? 함수 내부에서는 var가 재할당된 것을 인터프리터가 감지하므로 var는 지역 변수가 되지만, var가 할당되기 전에 사용하려고 하면 이런 오류가 발생합니다. 해결책은 함수 내부에 전역 변수를 추가하는 것입니다. 그러나 전역 변수도 함수를 실행한 후에 수정됩니다.
闭包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())
위 내용은 지역 변수와 전역 변수를 시작으로 Python의 변수 범위를 종합적으로 분석합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!