2013-04-22 4 views
3

는이 전 다음과 같은 기능을 가지고 있다고 가정 해 봅시다 다음과 같이 xplus1을 다시 정의하면 명명 충돌이 발생합니다.충돌하는 변수와 함수 이름

def xplus1(x): 
    s = xplusy(x, 1) 
    return s 

그것은 잘 작동합니다.

왜 그렇게 : 컴파일러가 변수와 함수 호출을 적절하게 구분할 수 없습니까?

주위에 어떤 방법이 있습니까?

+3

왜 당신의 인생을 복잡하게하는 방법이이 다른 범위 지정 관련 동작을 설명하는 정말 멋진 포스트는? 그냥 다른 이름을 써. – Maroun

+1

다음과 같이'return xplusy (x, 1)'를 할 수 있습니다 :''xplus1 (x) : return xplusy (x, 1) '' ' –

+0

다른 언어로 사용하는 것은 자연스러운 일입니다. 그것을 변경하는 것은 문제가되지 않지만 코드에 몇 가지 문자를 추가하는 것이 문제라면 나는 그걸로 문제가되지 않습니다. 왜 그것이 이론적으로 나에게 불분명한지 ... – sashkello

답변

12

파이썬에서 함수는 데이터이고 입력은 동적입니다.즉, 다음 행은 유효한 파이썬입니다.

def func(x): 
    return x + 3 

func = 3 

func은 이제 int입니다. 원래 함수 func은 더 이상 참조되지 않습니다. func이 원래 함수 였기 때문에 앞으로 어떤 유형의 데이터에 할당 할 수 있는지에 관계하지 않습니다.

정적 유형 지정이없고 "함수"가 유효한 데이터 유형이기 때문에 파이썬 인터프리터가 함수와 함수를 구별하는 것이 적절하지 않을 수 있습니다. 같은 이름으로 참조 된 데이터 조각. 따라서 주어진 범위 내에서 두 가지 다른 것을 의미하기 위해 동일한 비 한정 변수 이름을 사용할 수있는 방법이 없습니다.

특정 경우

당신의 xplus1 기능의 코드가 무엇을 의미하는 경우, 그것은 xplusy(x,1)의 값을 계산 "을 의미하고 변수 xplusy에 가치를 할당합니다 -하여 기능에 대한 참조를 잃고xplusy . " 그러나 함수의 범위 내에서 인터프리터는 해당 범위 밖의 변수에 할당 할 수 없으므로 할당 문을 작성하여 새로운 로컬 변수 xplusy을 도입한다고 가정합니다. 그러나 로컬 변수는 아직 정의되지 않았으므로 호출하려는 시도는 xplusy(x,1)입니다. 전역 적으로 정의 된 함수는 폴백으로 호출되지 않습니다. 다시 말하면, 두 개의 규정되지 않은 이름이 동일하고 동일한 범위의 다른 데이터를 가리킬 수 없기 때문입니다.


(이 대답을 구성하는 나의 시도 프롬프트로 주위를 재생하는 동안 나는 실제로 단지 발견) 규칙은 "한 범위 내에서 변수 이름에는 중복"입증되지 또 다른 예 :

>>> def f1(): 
...  a = xplusy(3,4) 
...  xplusy = 5 
...  print xplusy 
... 
>>> f1() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 2, in f1 
UnboundLocalError: local variable 'xplusy' referenced before assignment 
>>> def f1(): 
...  a = xplusy(3,4) 
...  print a 
... 
>>> f1() 
7 

이것은 범위이고 은 고유 한 이름이 필요하지 않음을 보여줍니다.


편집 : http://me.veekun.com/blog/2011/04/24/gotcha-python-scoping-closures/

+0

고마워, 지금은 ... – sashkello

+0

모듈 이름에서도 마찬가지입니까? 나는 모듈과 같은 이름을 가진 변수를 가지고 파이썬 스크립트를 유지하고있다. (시간, 당신이 궁금해했다면.) – Jack

+0

@ 잭 나는 당신이 무엇을 요구하고 있는지 잘 모르겠다. 'import' 문은 모듈 이름 (변수 이름이 아닌)을 변수에 할당하기 때문에 모듈과 같은 이름을 공유하는 전역 변수 나 지역 변수의 영향을받지 않습니다. 즉,'time = 3; epoch_time으로 시간 가져 오기 시간에서; 인쇄 시간; print epoch_time()'은'3' 다음에 신기원 이후의 초 수를 출력합니다. 그러나'time = 3; 시간 가져 오기 시간부터; print time'은''을 출력합니다. 왜냐하면'time' 변수는 import 문에 의해 재 할당되기 때문입니다. –

1

xplusy은 명시 적으로 xplusyglobal 인 경우를 제외하고 변경할 수없는 전역 변수로 범위에 존재하기 때문에 발생합니다.

def xplusy(x,y): 
    return x+y 

def xplus1(x): 
    global xplusy 
    xplusy = xplusy(x,1) 
    return xplusy 

그러나,이 것 xplusyint, float이든 xplusy를 참조 처음 후에는 TypeError의를 던질 것을 의미, 처음으로 돌아왔다.

더 많은 파이썬이 가장 가능성이

def xplus1(x): 
    return xplusy(x,1) 

것 할 수있는 방법 또는 functools 모듈 사용 :

from functools import partial 
xplus1 = partial(xplusy,y=1) #since you wanted to override y with 1 

당신이 상관하지 않는 경우 인수가 무시되는 대해를, 당신은 단순히 수 do

xplus1 = partial(xplusy,1) 
1

예를 들어, 콜백의 경우에는 funct 이온을 정적 이름 (funcName() 대신 funcName)으로 바꿉니다. 따라서 Python에서는 variable-name이 함수 용으로 예약되어 있습니다. 변수에 저장하는 LAMBDA 함수를 사용하는 방법과 비슷합니다.

3

파이썬 함수에서 다른 개체와 마찬가지로 의미하는 첫 번째 클래스 개체입니다.

더 자세한 정보에 대한 What are “first class” objects?

+4

글쎄, 함수는 Common Lisp의 first-class 객체이기도하지만 Common Lisp는 함수를위한 별도의 네임 스페이스를 가지고있다. –

1

파이썬에서, xplusy 아무것도 참조 할 수 있습니다. 이 작업을 수행 할 수 있습니다

def xplusy(x, y): 
    return x+y 

def otherfunction(x, y): 
    return x*y 

def xplus1(x): 
    xplusy = otherfunction 
    return xplusy(x, 1) 

그리고 xplusy 변수는 xplus1 범위에 otherfunction를 참조합니다.

xplus1(2) 
>>> 2 

결과는 2 * 1 대신 2 * 1입니다. 할당에주의하십시오. 필요한만큼 많은 변수를 사용하십시오.

+0

고마워, 이상하게 보입니다 :) – sashkello

관련 문제