본문 바로가기

프로그래밍/Python

Python 한 걸음 내딛기 : Part 3 [ 함수-1 ]

1주일에 하나씩 목표로 하고 있는 Python 정리네요. ^^;

함수를 한 번의 포스팅으로 하려고 했는데.. 정리하다보니.. 살짝 길어져서.. 나눕니다. ^^;


함수

- 여러 줄의 명령을 하나의 범위로 지정하여 특정한 역할을 하도록 만든 것.
- 프로그램에서 여러 번, 사용해야 하는 일을 함수로 만들어서 필요 시 호출해서 사용할 수 있다.
- 직접 필요한 함수를 만들 수 있으며, 이미 만들어져 있는 함수를 호출해서 사용할 수도 있다.

   

함수 정의

- def <함수명> (매개변수1, 매개변수, ….):

명령문..

Return value

   

   

함수 예제로 함수 한걸음 내딛기

함수 예제-1)

함수 예제-2)

def SumFunc(a,b):

sum = a+b

return sum

   

print(SumFunc(10,20))

def printBlog():

print("http://ThePlmingSpace.tistory.com")

   

- def는 함수를 선언하는 Keyword 이다.

- 함수 선언 시, 매개변수는 함수 내에서 사용하게 될 변수를 함수 호출 시에 가져오는 것이다.

이러한 매개변수를 포함하여 함수를 선언할 수도 있고(예제1), 포함하지 않고 선언할 수 있다(예제2).

- 함수 선언 시, def Keyword와 함수명 뒤에는 ':' 을 써준다.

- 함수의 범위는 Python에서 늘 그러하듯이, Indent를 통해서 범위를 지정하게 된다.

- return은 함수를 종료 시에, 함수를 호출한 곳에 값을 넘겨주는 역할이며 넘겨줄 값이 없을 경우에는

생략이 가능하며 이 경우에는 None을 반환하게 된다. 이는 False가 되기도 한다.

※ if(printBlog()) 는 return 받는 값이 None이므로 False가 된다.

- 함수를 호출 시에는 반드시 함수명 뒤에 ( )를 써서 호출해야 한다.

함수도 하나의 객체로 취급되기 때문에, 함수명은 해당 함수 객체를 가리키는 변수일 뿐이다.

이를 이해하기 위해 아래 함수 예제-3을 보면,

   

함수 예제-3

함수 예제-3 : 결과값

def printNick_Name():

print("NetworkZIGI-네떡지기(고재성)")

   

print(printNick_Name)

print(printNick_Name())

<function printNick_Name at 0x01B18150>

NetworkZIGI-네떡지기(고재성)

None

   

- 예제-3에서 간단히 문장을 하나 출력하는 함수를 선언하고, 각각 함수명과 함수명()으로 호출을 하여 출력한다.

이에 대한 결과값을 보면, 함수명을 출력을 하게되면 이는 하나의 객체이기 때문에 해당 객체의 주소를 출력하

하게 된다. 그리고 정상적으로 함수() print 안에서 출력하면 해당 함수가 먼저 실행되기 때문에 함수에 선언한

내용이 먼저 출력이 되고, 함수에서는 별도의 return 값을 주지 않기 때문에 None을 받게 되고 이를 받은

print함수에서는 None을 출력하게 된다.

- 바로 위에서 설명 시에 얘기했던 것처럼, print 함수에서 함수를 호출했다. print도 바로 함수라는 점이고 이것이

처음에 얘기했던 기존에 선언되어 있는 Python의 내장함수가 되고, printNick_Name는 사용자 정의 함수가 된다.

   

함수에서의 범위(Scope), 한 걸음 내딛기 하나!

- Python의 Scope는 Indent로 구분이 되고, 함수도 마찬가지이다.

- 모든 변수는 자신이 선언된 Scope 내에서만 유효하다. 따라서, 함수 안에서 선언된 변수는 함수 안에서만 유효

하며, 함수의 Scope를 벗어나면 해당 객체는 사용할 수 없다.

- 모든 변수는 자신이 선언된 Scope 내에서만 유효하다는 것은, 자신의 Socpe를 포함한 자신 Scope 안에서

선언된 하위 Scope 안도 포함되게 된다. Scope를 벗어나서 사용이 불가하다는 것은 결국 상위 Scope에서는

하위 Scope에 선언된 내용을 알 수 없다는 것이다.

- 예제 4를 보면, scopeTest 함수 내에서 nick이라는 변수를 만들어서 사용하였고,

real이라는 변수는 상위 Scope(여기서는 전역공간임)에 선언하여 사용하였다.

- 이 경우에 scopeTest 내에서는 모두 접근이 가능한 변수이기 때문에, 정상적으로 출력이 되지만,

외부에서 name과 nick을 접근하려고 하면, real은 동일한 scope이기 때문에 접근이 되지만

nick는 함수 내에서 선언된 변수이기 때문에 외부 scope에서는 알 수가 없고, 따라서 nick이라는 변수가

선언된 적이 없다고 오류가 발생하게 된다.

   

함수 예제-4

함수 예제-4 결과값

real = "고재성"

   

def scopeTest1():

nick = "네떡지기"

print(nick)

print(real)

   

scopeTest1()

print(real)

print(nick)

네떡지기

고재성

고재성

File "C:/FunctionTest.py", line 12, in <module>

print(nick)

NameError: name 'nick' is not defined

   

   

   

함수에서의 범위(Scope), 한 걸음 내딛기 둘!

- 함수의 매개변수로 전달되는 것은, 실제 변수의 값이 있는 주소를 전달하게 된다.

- 매개변수로 전달받은 값을 새로운 값으로 변경을 하면, 실제 원래의 값이 변경되는 것이 아니라 새로운 값의

의 주소로 바뀌게 되는 것 뿐이다.

- 예제-5를 보면, real이라는 변수를 함수 호출 시 전달을 하게 되고, scopeTest2 함수 내에서는 이 값을 보면

실제 기존에 선언된 값이 있는 주소 값을 그대로 가리키고 있음을 볼 수 있고, 만약에 새로운 값을 할당하면

해당 변수는 새로운 값이 있는 주소 값으로 바뀌게 된다. 하지만, 함수를 벗어나게 된 이후에 원래의 real을

보면 여전히 기존의 값을 유지하고 있음을 알 수 있다.

- 만약 함수 외부에 선언된 변수와 함수 내부에 선언된 변수가 있을 경우에는 함수 내부에서 선언된 것이

더 우선하게 된다. 만약에 자신의 Scope 내에 없는 경우에는 상위 Scope를 확인하게 된다.

이는 어쩌면 너무나도 당연하다, 내가 쓰려고 하는 것이 여러 개 있으면 가장 가까운 것을 가져다 쓰는 것이다.

- 함수 내부에서 전역영역에서 선언한 변수를 그대로 가져와서 쓸 수도 있는 데, 이는 global이라는 keyword를

사용하여 함수 내부에서 동일한 변수 명으로 변수를 선언한다. 이 경우에는 함수 내부에서 값을 변경하면

그대로 반영되게 된다.

- 예제-6을 보면, real과 nick을 함수 외부(전역영역)에서 선언했고, scopreTest3에서 동일한 이름의 변수를

사용을 하는데, real이라는 변수는 그냥 동일한 이름으로 사용을 하고 nick은 global keyword를 사용한다.

그리고, 각 새로운 값으로 초기화해서 써서 출력하면 함수 내에서는 초기화한 값으로 출력이 되고

함수를 나와서, 각 변수를 출력하면, global을 써서 함수 내에서 쓴 nick만 변경된 것을 볼 수 있다.

함수 내에서 전역공간의 변수를 가져다가 사용하기 위한 예제라고 볼 수 있다.

   

함수 예제-5

함수 예제-5 결과값

함수 예제-6

함수 예제-6 결과값

real = "고재성"

   

def scopeTest2(name):

print(id(name))

name = "네떡지기"

print(name)

print(id(name))

   

print(id(real))

scopeTest2(real)

print(id(real))

print(real)

20301248

20301248

네떡지기

28458784

20301248

고재성

real = "고재성"

nick = "고재성"

   

def scopeTest3():

real = "네떡지기"

global nick

nick = "네떡지기"

print(real)

print(nick)

   

scopeTest3()

print(real)

print(nick)

네떡지기

네떡지기

고재성

네떡지기

   

- 함수 예제 5/6의 경우를 이해하기 위해 간단한 개념도(?) 정도로 아래의 그림을 보면..

 

- 일반적인 매개변수 전달 시인 예제5의 경우에는 real을 매개변수로 전달하게 되면,

real이 가지고 있는 '고재성'이라는 값의 주소를 복사하여 새로운 공간(200)에 할당해서 사용한다.

이 경우에는 name이 가리키는 곳의 공간(1000)이 동일하기 때문에 그 값을 그대로 쓸 수 있지만

만약 이 값을 새로운 값으로 변경하게 되면 해당 값이 있는 공간(2000)을 가리키도록 변경된다.

하지만, 이 경우에는 real이라는 값에는 영향을 미치지 않는다.

   

 

- Global keyword를 사용하게 되면, 개념적으로 그냥 전역변수의 nick을 그대로 쓴다고 이해해도 되겠지만

위의 그림과 같이 함수 내에서의 nick(g-nick으로 표기)이 전역변수와 동일한 곳을 가리키도록 하고,

그 곳에는 실제 값이 있는 공간(1000)을 지칭하는 값이 있다.

이 때 함수 내의 nick의 값을 변경하게 되면, 전역공간과 동일한 곳(100)에 새로운 값을 가리키는 값(2000)을

넣기 때문에 전역 공간의 값에도 함께 영향을 받게 된다.