2012-12-26 2 views
4

저는 로컬 변수로 작업하는 함수를 가지고 있으며, 함수가 완료된 후 최종 변수를 다시 전달합니다. 이 변수가 함수 앞에 있었지만 전역 변수가 지역 변수와 함께 업데이트된다는 것을 기록하고 싶습니다. 여기Python : 로컬 변수가 신비하게 업데이트되었습니다. 전역 변수

def Turn(P,Llocal,T,oflag): 
    #The function here changes P, Llocal and T then passes those values back 
    return(P, Llocal, T, oflag) 

#Later I call the function 
#P and L are defined here, then I copy them to other variables to save 
#the initial values 

P=Pinitial 
L=Linitial 
P,L,T,oflag = Turn(P,L,T,oflag) 

내 문제가 L이다 (그 상당히 긴) 내 코드의 축약 된 버전이며 Llocal가 업데이트 될 때 Linitial 모두 정확하게 업데이트됩니다,하지만 난 Linitial이 변경되지 싶습니다. P는 변하지 않으므로 여기서 무슨 일이 일어나고 있는지 혼란스러워합니다. 도움? 감사!

용감한 사람들을위한 전체 코드는 여기에 있습니다 : https://docs.google.com/document/d/1e6VJnZgVqlYGgYb6X0cCIF-7-npShM7RXL9nXd_pT-o/edit

+2

:

new_list = old_list[:] 

여기에 좋은 설명이있어? 보고있는 것을 보여주는 완벽한 독립형 실행 가능한 예제를 제공 할 수 있습니까? –

+0

P는 int이고 L은리스트입니다. T는 int이고, oflag는 bool입니다. 나는 IDLE의 디버거를 통해이 문제를 발견했다. 글로벌 변수와 로컬 변수를 표시하면, L, Linitial, Llocal의 3 개가 동시에 변경되는 것을 알 수 있습니다. 여기에 전체 코드를 업로드 할 수 있지만 몇 백 줄입니다. 내가 지금 걱정하고있는 부분은 190과 57 주위에서 시작합니다. 현재 66 행에서 오류가 발생하지만 오류의 근본적인 원인은이 변수를 업데이트하는 것입니다. – mykinz

+0

[PEP-8] (http://www.python.org/dev/peps/pep-0008/)은 클래스 이름에'CapWords'를 예약 할 것을 권장합니다. –

답변

1

목록을 변경할 수 있습니다. 함수에 목록을 전달하고 해당 함수가 목록을 수정하면 같은 목록에 바인딩 된 다른 이름의 수정 사항을 볼 수 있습니다. 이것에

L = Linitial 

:

L = Linitial[:] 

이 슬라이스가 목록의 단순 복사본을 만들어이 문제를 해결하려면

이 라인을 변경해보십시오. L에 저장된 목록에서 항목을 추가하거나 제거하면 Lintial 목록이 변경되지 않습니다.

딥 복사본을 만들려면 copy.deepcopy을 사용하십시오.


P은 정수이기 때문에 동일한 문제가 발생하지 않습니다. 정수는 불변입니다.

+0

copy.deepcopy 및 L = Linitial [:]을 사용하여 시도했지만 이전과 같은 오류가 발생합니다. 디버거와 함께 작업 중이므로 무슨 일이 벌어지는 지 다시 볼 것입니다. 고맙습니다! – mykinz

+0

이제 작동합니다! 실제로 Linitial을 정의 할 때와 L을 다시 정의 할 때 모두 얕은 복사본을 두 번 만들어야했습니다. 감사합니다! – mykinz

2

문제는 P와 L은 boundobjects에, 자신을 가치없는 names을 점이다. 매개 변수를 함수에 매개 변수로 전달하면 실제로 바인딩의 복사본을 P와 L에 전달합니다. 즉, P와 L이 변경 가능한 개체 인 경우 해당 개체에 대한 모든 변경 내용을 함수 호출 외부에서 볼 수 있습니다 .

copy 모듈을 사용하면 이름 값의 복사본을 저장할 수 있습니다.

+0

메모로서'copy'는 모듈이 아니라 함수입니다. –

+0

나는이 함수가 포인터를 받아서이 객체에서 초기 객체가 충분하다는 것을 이해한다고 생각한다. 그러나 불변 객체는 대개 할당 (예 : 숫자 및 문자열)에 복사 된 반면 변형 객체는 새 이름에 동일한 포인터를 할당하므로 동일한 인스턴스를 참조하는 두 개의 이름이 있습니다. –

+0

@ Nisan.H Python 언어에는 '포인터'라는 개념이 없으므로 유용하지 않습니다. (구현체 인 cPython은 포인터를 사용하지만). 그리고 불변 개체는 "할당시 복사"되지 않습니다. 이름은 할당 된 모든 것에 다시 바인딩됩니다. – jknupp

0

파이썬에서 변수는 메모리의 객체 또는 값에 대한 참조 일뿐입니다. 당신이 목록 x 때 예를 들어, : 그래서

x = [1, 2, 3] 

를 할 때 당신은 (당신이 단지 x에 의해 참조되는 객체에 대한 새로운 참조 (y)를 작성,의는 y를 호출하자, 다른 변수에 x를 할당 [1, 2, 3] 목록).

y = x 

당신이 x를 업데이트

, 당신은 실제로 즉 목록 [1, 2, 3] x가 가리키는 객체를 업데이트하고 있습니다. y은 동일한 값을 참조하므로 업데이트 된 것처럼 보입니다.

변수는 객체에 대한 참조 일뿐입니다.당신이 정말로 목록을 복사하려면

, 당신이 할 갈까요 : 객체의 유형은 무엇 http://henry.precheur.org/python/copy_list

관련 문제