파이썬과 함수, 스코프



파이썬과 함수

함수는 사실 간단하다. 우리가 교육과정에서 배웠던 것과 같다. 대신 어떤 동작을 하는 것을 내가 정의하는게 다를 뿐. 내가 프로그래밍하면서 잡은 함수의 개념은 “입력된 값에 대하여 특정 연산을 한 결과를 돌려주는 것”이 함수이다. 다른 프로그래밍 언어에서도 함수의 정의는 별로 다르지 않다. 그러면, 중요한 것은 파이썬에서는 함수를 어떻게 정의하고, 사용하며, 어떤 형태로 존재하는가이다.

# 파이썬에서의 함수 정의
>>> def 함수명([*인자]):
    	전달 받은 인자를 가지고 수행할 코드 블럭
        return 결과 # 반환 값

으로 볼 수 있는데, 인자는 있을 수도 없을 수도 있으며, 반환 값 또한 있을 수도, 없을 수도 있다. 즉,

  • 인자 값 받음, 반환해서 사용할 값 없음
  • 인자 값 받음, 반환해서 사용할 값 있음
  • 인자 값 안 받음, 반환해서 사용할 값 없음
  • 인자 값 안 받음, 반환해서 사용할 값 있음

의 네 가지 경우의 함수가 있다.

라고 하지만 사실 알아서 작성해서 써와 같은 느낌, 프로그래머가 필요하면 받고 없으면 안받고 필요없으면 반환 안하고, 필요하면 하고 하는거지

반환해서 사용할 이라고 쓴 데는 이유가 있다. 사실 모든 함수는 반환을 하기 때문이지.

추가적으로 알아 둬야 할 부분은, 반환 값이 없을 때, 명시를 하지 않아도 되고 명시해도 된다는 점.

#두 가지 방식의 반환 값이 없는 함수 선언
def 함수명([*인자]):
    전달 받은 인자를 가지고 수행할 코드 블럭
    return None # None 은 '값이 없음'을 의미

def 함수명([*인자]):
    전달 받은 인자를 가지고 수행할 코드 블럭 # 이 경우 알아서 None 반환

파이썬 함수, 인자(Parameters)

함수에 전달되는 어떤 값들을 모두 인자들(Parameters)라고 부른다.

이러한 인자는 함수의 정의에 따라, 전달되는데 기본적으로 해당하는 위치로 매핑시킨다.

>>> def functionEx1(name, age):
    	print("{}은 {}세 입니다.".format(name, age))

라고 함수가 정의 되어 있을 때, 첫 번째 위치한 인자는 name이고 두 번째 인자는 age이다. 라고 위치적으로 매칭시키는 것이다.

다만, Keyword에 의한 매칭법도 있다. 인자를 전달할 때 이게 어떤 인자인지를 알려주는 방법으로

>>> functionEX1(name='홍길동', age='16')
홍길동은 16 입니다.
>>> functionEX1(age='16', name='홍길동')
홍길동은 16 입니다.

처럼 Keyword에 의하여 매칭되는 방식이다.

추가적으로 함수의 인자에 기본 값(Default)를 설정하는 방법을 보자.

파이썬의 스코프(Scope)

이야. . . 스코프 개념이 여기서 뜬금없이 진행될 줄은 몰랐다. 강의 순서 왜이래

파이썬에서 스코프 또한, 다른 프로그래밍 언어와 다를 것이 없다.

스코프는 정의하자면, 해당 변수가 보이는(유효한) 구역으로 생각 할 수 있다.

이게 보이는(유효한)이라고 쓴게 저 두가지 의미를 혼합한 듯한 느낌이 스코프 이기 때문이다.

일반적으로 변수의 스코프를 이야기 할 때, 처음에 두 가지를 알려주는데,

  • 전역변수(Global Variable) : 함수 밖에서 선언되어, 전체 구역에서 보이는 변수
  • 지역변수(Local Variable) : 함수 내부에 선언되어, 해당 구역 안에서 보이는 변수

이다.

일반적으로 전역변수에 상수(Constant)를 선언하는 경우가 많은데, 파이썬은 상수(Constant)를 지원하지 않기에, 전역변수를 대문자로 선언하는 것을 통해 상수임을 알리는 식으로 표현한다.

CONSTVALUE = 223 # 전역변수로 상수임을 알리는 방법

이런식이다.

>>> def functionEx1(name='이름', age=0):
    	print("{}은 {}세 입니다.".format(name, age))
>>> def functionEx1()
이름은 0 입니다.

쉽죠? 함수의 정의부분에서 defalut값으로 설정하고 싶은 값을 같이 선언(할당)해주면 된다.

이렇게 함수를 쓰다보면, 유동적 인자 수를 가지게 되는 함수를 선언해야 하는 경우가 생기는데, 이런 경우 packing을 활용하여 함수를 작성한다.

>>> def functionEx2(*colors):
    	for color in colors
        	print(color)

>>> functionEx2('red')
red
>>> functionEx2('red', 'orange', 'yellow')
red
orange
yellow

생각보다 어렵지 않다.

다만, 이 경우 함수로 전달되야 하는 인자가 없어도 되기에, 특정 갯수의 인자는 꼭 받고, 나머지는 자유롭게 하고싶다면 다음과 같이 정의한다.

# 꼭 받고 싶은 인자의 개수가 2개인 함수
>>> def functionAtLeast2(color1, color2, *other_colors):
		print('color1 : ', color1)
		print('color2 : ', color2)
		for other_color in other_colors:
			print('color')

반대로 unpacking을 활용하여, 인자를 전달하는 방법도 당연히 있을거다.

>>> colors = ['white', 'yellow', 'black']
	functionAtLeast2('red', 'blue', *colors)

# 또는
>>> colors = ['white', 'yellow', 'black']
	functionAtLeast2(*colors)

이렇게 말이다.

더 나아가 가변인자를 활용하는 방법이 있는데, 가변인자를 활용하면, 객체(Class)로 넘어가면서 다양한 기능 구현에 사용할 수 있으니 알아두자. 나중에 나올 상속과 오버라이딩 관련!

# 가변인자를 이용한 함수 구현
>>> def functionEx3(**scores): # **scores를 통하여 dict으로써 다수의 인자를 받을 수 있게 함
    	for key, score in scores.items():
            print(key, score)

이런식으로 구현한다.

익명함수(Anonymous Function)

익명함수?? 이게 뭐. . 야, 알고 봤더니 lambda 였어. . . 스트레스

파이썬에서 lambda를 통하여 익명함수를 정의할 수 있다.

# 형식
>>> 함수명 = lambda 인자 : 코드

# 예시
>>> def mysum1(x, y): # 일반 함수 선언
    	return x + y
>>> mysum2 = lambda x, y : x + y # 익명함수 선언

>>> print(mysum1(1, 2))
3
>>> print(mysum2(1, 2))
3

# 가변 인자를 받는 익명함수
>>> mysum3 = lambda *params : sum(params) # 람다 함수로 가변 인자 *params를 받아 내장함수 sum에 전달함
>>> print(mysum3(1, 2, 3, 4, 5, 6, 7))
28

가변 인자를 받는 익명함수 굳이 내장함수 sum 쓸거면 sum(1, 2, 3, 4, 5, 6, 7)하지 그랬냐

파이썬과 1급 함수/클래스

파이썬은 1급 함수/클래스를 지원한다.

무슨 소리인가 싶더만, 잘 들어보니 각 함수를 변수로 활용가능이라고 설명했다. Java의 변수와 객체가동작하는 방식과 유사한 것 같은 느낌, 대신 함수를 객체로써 보는건 신박했달까

런타임에!

  • 함수/클래스를 생성 가능
  • 함수/클래스를 변수에 할당 가능
  • 함수/클래스를 인자나 리턴값으로 전달 가능

한 특징이 있다. 이것은 놀이터에서 테마파크로 옮긴 느낌!? 장난쳐볼 것이 늘었다

백문이 불여일견! 예시를 통해 파악하자

>>> mysum1 = lambda x, y : x + y # lambda를 통한 익명함수 선언
>>> mysum2 = mysum2 # 함수/클래스를 변수에 할당 가능함을 보여줌.
>>> mysum2(10, 20)
30

>>> def myfn(fn, x, y): # 함수를 인자로 받아 다시 함수를 반환하는 함수 선언
    	return = fn(x, y) # 함수를 생성하여 반환
>>> myfn(mysum1, 20, 30)
50
>>> myfn(lambda x, y : x * y, 100, 200) # 익명함수 선언 후 인자를 주어 함수를 만들어버림
20000

하지만 뭔가 단순하다. 1차원적인 느낌이지. 그래서 나온다. 고차함수!

고차함수(High Order Function)

  • 다른 함수를 생산/소비하는 함수
  • 다른 함수를 인자로 받거나, 그 결과로 함수를 반환하는 함수
>>> def base_cal(base): # base_cal이라는 함수를 선언
    	wrap = lambda x, y : base + x + y # lambda를 통해 base, x, y를 사용하는 새로운 함수 생성
        return wrap # 함수를 반환

>>> calc_10 = base_cal(10) # base_cal은 base를 기본으로 x, y를 더하는 함수를 반환, 그게 calc_10 이 된다
>>> calc_10(1, 2)
13
>>> calc_10(8, 13)
31

이번엔 여기까지 : )