참조로 파이썬 함수 호출
일부 언어에서는 ref 또는 val 과 같은 특수 예약어를 사용하여 참조 또는 값으로 매개 변수를 전달할 수 있습니다 . Python 함수에 매개 변수를 전달하면 함수를 떠날 때 매개 변수의 값이 변경되지 않습니다.이를 수행하는 유일한 방법은 전역 예약어 를 사용하는 것입니다 (또는 현재 이해하고 있음).
예 1 :
k = 2
def foo (n):
n = n * n #clarity regarding comment below
square = n
return square
j = foo(k)
print j
print k
보여줄 것이다
>>4
>>2
k가 변경되지 않음을 표시
이 예에서 변수 n은 변경되지 않습니다.
예 2 :
n = 0
def foo():
global n
n = n * n
return n
이 예에서는 변수 n이 변경됩니다.
Python에서 함수를 호출 하고 매개 변수 가 전역을 사용하는 대신 값 또는 참조 매개 변수 임을 Python에 알리는 방법 이 있습니까?
둘째, A 레벨 Cambridge 시험에서 이제 함수는 단일 값을 반환하는 반면 프로시 저는 둘 이상의 값을 반환한다고 말합니다 . 80 년대에는 함수에 return 문이 있고 절차에는없는 것을 배웠습니다. 이제 이것이 잘못된 이유는 무엇입니까?
Python에서 참조로 간단한 기본 형식을 전달할 수는 없지만 다음과 같은 작업을 수행 할 수 있습니다.
def foo(y):
y[0] = y[0]**2
x = [5]
foo(x)
print x[0] # prints 25
그러나 그것은 그것에 대해 이상한 방법입니다. Python에서는 둘 이상의 값을 반환 할 수도 있으므로 참조에 의한 전달의 일부 사용 사례가 덜 중요합니다.
def foo(x, y):
return x**2, y**2
a = 1
b = 2
a, b = foo(a, b) # a == 2; b == 4
이와 같은 값을 반환하면 튜플로 반환되고 차례로 풀립니다.
편집 : 이것에 대해 생각하는 또 다른 방법은 파이썬에서 참조로 변수를 명시 적으로 전달할 수는 없지만 전달 된 객체의 속성을 수정할 수 있다는 것입니다. 제 예 (및 기타)에서는 목록의 구성원을 수정할 수 있습니다. 그러나 전달 된 변수를 완전히 재 할당 할 수는 없습니다. 예를 들어 다음 두 코드는 비슷한 작업을 수행하지만 결과가 다른 것처럼 보입니다.
def clear_a(x):
x = []
def clear_b(x):
while x: x.pop()
z = [1,2,3]
clear_a(z) # z will not be changed
clear_b(z) # z will be emptied
본질적으로 세 가지 종류의 '함수 호출'이 있습니다.
- 가치로 전달
- 참조로 전달
- 개체 참조로 전달
Python은 PASS-BY-OBJECT-REFERENCE 프로그래밍 언어입니다.
첫째, 변수와 변수 (객체)의 값은 별개의 것임을 이해하는 것이 중요합니다. 변수는 개체를 '가리 킵니다'. 변수는 개체가 아닙니다. 다시:
변수는 객체가 아닙니다
예 : 다음 코드 줄에서 :
>>> x = []
[]는 빈 목록이고 x는 빈 목록을 가리키는 변수이지만 x 자체는 빈 목록이 아닙니다.
변수 (위의 경우 x)를 상자로 간주하고 변수 ([])의 '값'을 상자 안의 개체로 간주합니다.
객체 참조로 통과 (파이썬의 경우) :
여기에서 "개체 참조는 값으로 전달됩니다."
def append_one(li):
li.append(1)
x = [0]
append_one(x)
print x
여기서 x = [0] 문은 객체 [0]을 가리키는 변수 x (상자)를 만듭니다.
호출되는 함수에서 새 box li이 생성됩니다. li의 내용은 box x의 내용과 동일합니다. 두 상자 모두 동일한 개체를 포함합니다. 즉, 두 변수 모두 메모리에서 동일한 객체를 가리 킵니다. 따라서 li이 가리키는 객체의 변경 사항은 x가 가리키는 객체에도 반영됩니다.
결론적으로, 위 프로그램의 출력은 다음과 같습니다.
[0, 1]
노트 :
변수 li이 함수에서 재 할당되면 li은 메모리에있는 별도의 개체를 가리 킵니다. x는 이전에 가리키는 메모리의 동일한 객체를 계속 가리 킵니다.
예:
def append_one(li):
li = [0, 1]
x = [0]
append_one(x)
print x
프로그램의 출력은 다음과 같습니다.
[0]
참조로 통과 :
호출 함수의 상자가 호출 된 함수로 전달됩니다. 암시 적으로 상자의 내용 (변수 값)은 호출 된 함수에 전달됩니다. 따라서 호출 된 함수의 상자 내용에 대한 변경 사항은 호출 함수에 반영됩니다.
가치로 통과 :
호출 된 함수에 새 상자가 생성되고 호출 함수 의 상자 내용 사본 이 새 상자에 저장됩니다.
도움이 되었기를 바랍니다.
좋아, 내가 찔러 볼게. 파이썬은 일반적으로 "참조"또는 "값"으로 생각하는 것과는 다른 객체 참조를 통과합니다. 이 예를 보자 :
def foo(x):
print x
bar = 'some value'
foo(bar)
따라서 값이 'some value'인 문자열 객체를 만들고라는 변수에 "바인딩"합니다 bar
. C에서는 bar
'어떤 값'에 대한 포인터 와 유사합니다 .
를 호출하면 그 자체로 foo(bar)
전달되지 않습니다 bar
. bar
's value :'some value '에 대한 포인터를 전달하고 있습니다. 이 시점에서 동일한 문자열 개체에 대한 두 개의 "포인터"가 있습니다.
이제 다음과 비교하십시오.
def foo(x):
x = 'another value'
print x
bar = 'some value'
foo(bar)
여기에 차이점이 있습니다. 라인에서 :
x = 'another value'
실제로의 내용을 변경하지 않습니다 x
. 사실 그것은 불가능합니다. 대신 '다른 값'값을 사용하여 새 문자열 개체를 만듭니다. 그 할당 연산자? " x
새 값으로 가리키는 것을 덮어 쓴다"는 말이 아닙니다 . " x
대신 새 개체를 가리 키도록 업데이트 "라는 의미입니다. 그 줄 뒤에는 'some value'( bar
가리키는)와 'another value'( x
가리키는 ) 라는 두 개의 문자열 객체가 있습니다 .
이것은 서투 르지 않습니다. 작동 방식을 이해하면 아름답고 우아하고 효율적인 시스템입니다.
다음 설명이 잘 요약되기를 바랍니다.
여기서 고려해야 할 두 가지 사항이 있습니다. 변수와 객체입니다.
- 변수를 전달하는 경우 값으로 전달됩니다. 즉, 함수 내의 변수에 대한 변경 사항은 해당 함수에 국한되어 있으므로 전역 적으로 반영되지 않습니다. 이것은 'C'와 같은 행동에 가깝습니다.
예:
def changeval( myvar ):
myvar = 20;
print "values inside the function: ", myvar
return
myvar = 10;
changeval( myvar );
print "values outside the function: ", myvar
O / P :
values inside the function: 20
values outside the function: 10
- 목록과 같이 변경 가능한 객체 내에 패킹 된 변수를 전달하는 경우 객체가 다시 할당되지 않는 한 객체에 대한 변경 사항이 전역 적으로 반영됩니다.
예:
def changelist( mylist ):
mylist2=['a'];
mylist.append(mylist2);
print "values inside the function: ", mylist
return
mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist
O / P :
values inside the function: [1, 2, 3, ['a']]
values outside the function: [1, 2, 3, ['a']]
- 이제 개체가 다시 할당되는 경우를 고려하십시오. 이 경우 객체는 이것이 발생하는 함수에 로컬 인 새 메모리 위치를 참조하므로 전역 적으로 반영되지 않습니다.
예:
def changelist( mylist ):
mylist=['a'];
print "values inside the function: ", mylist
return
mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist
O / P :
values inside the function: ['a']
values outside the function: [1, 2, 3]
Python은 값에 의한 전달도 참조에 의한 전달도 아닙니다. 그것은 더의의 "개체 참조가 값에 의해 전달된다" 와 같이 여기 :
Here's why it's not pass-by-value. Because
def append(list): list.append(1) list = [0] reassign(list) append(list)
returns [0,1] showing that some kind of reference was clearly passed as pass-by-value does not allow a function to alter the parent scope at all.
Looks like pass-by-reference then, hu? Nope.
Here's why it's not pass-by-reference. Because
def reassign(list): list = [0, 1] list = [0] reassign(list) print list
returns [0] showing that the original reference was destroyed when list was reassigned. pass-by-reference would have returned [0,1].
For more information look here:
If you want your function to not manipulate outside scope, you need to make a copy of the input parameters that creates a new object.
from copy import copy
def append(list):
list2 = copy(list)
list2.append(1)
print list2
list = [0]
append(list)
print list
So this is a little bit of a subtle point, because while Python only passes variables by value, every variable in Python is a reference. If you want to be able to change your values with a function call, what you need is a mutable object. For example:
l = [0]
def set_3(x):
x[0] = 3
set_3(l)
print(l[0])
In the above code, the function modifies the contents of a List object (which is mutable), and so the output is 3 instead of 0.
I write this answer only to illustrate what 'by value' means in Python. The above code is bad style, and if you really want to mutate your values you should write a class and call methods within that class, as MPX suggests.
The answer given is
def set_4(x):
y = []
for i in x:
y.append(i)
y[0] = 4
return y
and
l = [0]
def set_3(x):
x[0] = 3
set_3(l)
print(l[0])
which is the best answer so far as it does what it says in the question. However,it does seem a very clumsy way compared to VB or Pascal.Is it the best method we have?
Not only is it clumsy, it involves mutating the original parameter in some way manually eg by changing the original parameter to a list: or copying it to another list rather than just saying: "use this parameter as a value " or "use this one as a reference". Could the simple answer be there is no reserved word for this but these are great work arounds?
In Python the passing by reference or by value has to do with what are the actual objects you are passing.So,if you are passing a list for example,then you actually make this pass by reference,since the list is a mutable object.Thus,you are passing a pointer to the function and you can modify the object (list) in the function body.
When you are passing a string,this passing is done by value,so a new string object is being created and when the function terminates it is destroyed. So it all has to do with mutable and immutable objects.
Python already call by ref..
let's take example:
def foo(var):
print(hex(id(var)))
x = 1 # any value
print(hex(id(x))) # I think the id() give the ref...
foo(x)
OutPut
0x50d43700 #with you might give another hex number deppend on your memory
0x50d43700
참고URL : https://stackoverflow.com/questions/13299427/python-functions-call-by-reference
'development' 카테고리의 다른 글
`float`를 초기화 할 때`float`로 캐스팅하는 것과 접미사로`f`를 추가하는 것의 차이점은 무엇입니까? (0) | 2020.12.03 |
---|---|
조건문에서 쉼표의 장점은 무엇입니까? (0) | 2020.12.03 |
React에서 여러 줄 텍스트 문자열을 렌더링하는 방법 (0) | 2020.12.02 |
phpMyAdmin-오류> 잘못된 형식 매개 변수? (0) | 2020.12.02 |
chm 뷰어가 내용을 표시 할 수 없습니다. (0) | 2020.12.02 |