함수

maro·2024년 3월 14일

함수 parameter와 return value

parameter: 함수가 호출하는 곳으로 부터 입력받는 값을 저장하는 변수

  • argument(인자): 호출할 때 파라미터에 전달하는 값

return value: 함수의 처리결과로 호출하는 곳에 전달(반환)하는 값.

return value(반환값)

함수가 호출받아 처리한 결과값으로 호출한 곳으로 반환하는 값이다.
함수 구현부에 return [값] 구문을 사용해 반환한다.

  • return
    - 함수가 정상적으로 끝났고 호출한곳으로 돌아간다.
    - 보통은 함수 구현의 마지막에 넣지만 경우에 따라 중간에 올 수 있다.

  • return 반환값
    - 호출한 곳으로 값을 가지고 돌아간다. (반환한다)
    - 반환값이 없을 경우 None을 반환한다.
    - 함수에 return 구문이 없을 경우 마지막에 return None이 실행된다.

여러개의 값을 return 하는 경우 자료구조로 묶어서 전달해야한다.

  • 함수는 한개의 값만 반환할 수 있다.
def greet4(name) : 
    if name == None :
        return #함수실행을 (정상적) 종료하고 호출한 곳으로 돌아가라.
    txt = f"{name} 님 안녕하세요.\n반갑습니다."
    return txt
result = greet4("홍길동") 
print(result)

홍길동 님 안녕하세요.
반갑습니다.

print(greet4(None))

None

print(greet4("이순신")) # 반환된 값을 바로 출력

이순신 님 안녕하세요.
반갑습니다.

#return 값이 여러개인 경우. -> 자료구조를 이용해서 묶어서 반환.
#return 값은 한개만 가능.
def calculate(n1, n2) : # 두개 숫자를 받아서 +, -, *, / 처리
    r1 = n1 + n2
    r2 = n1 - n2
    r3 = n1 * n2
    r4 = n1 / n2
    #return [r1, r2, r3, r4]
    return r1, r2, r3, r4 #튜플로 묶어서 반환
v = calculate(10, 2)
v

(12, 8, 20, 5.0)

v1, v2, v3, v4 = calculate(10, 2)
print(v1, v2, v3, v4)

12 8 20 5.0

Parameter (매개변수)

기본값이 있는 Parameter

매개변수에 값을 대입하는 구문을 작성하면 호출할 때 argument 가 넘어오지 않으면 대입해놓은 기본값을 사용한다.
함수 정의시 기본값 없는 매개변수, 있는 매개변수를 같이 선언할 수 있다.

  • 이때 기본값 없는 매개변수들을 선언하고 그 다음에 기본값 있는 매개변수들을 선언한다.
def greet(name = None) :
    if name == None :
        print("안녕하세요")
    else :
        print(f"{name}님 안녕하세요.")
greet("이순신")
greet() #name은 None을 사용

이순신님 안녕하세요.
안녕하세요

def greet5(name, age, address = None) :
    print(name, age, address)
greet5("이순신", 20)

이순신 20 None

def greet6(age, name = "없음", address = None) : #파라미터에 기본값을 준 파라미터는 가장 앞에 쓰면 안됨.
    print(age, name, address) 
greet6(20) #기본 값이 없는 것은 필수로 값을 넣어줘야함.

20 없음 None

Positional argument와 Keyword argument

Argument는 함수/메소드를 호출할 때 전달하는 입력값을 말한다.

  • Argument는 전달하는 값이고 Parameter는 그 값을 저장하는 변수

Positional argument

  • 함수 호출 할때 argument(전달인자)를 Parameter 순서에 맞춰 값을 넣어서 호출.

keyword argument

  • 함수 호출할 때 argument를 Parameter변수명 = 전달할값 형식으로 선언해서 어떤 parameter에 어떤 값을 전달할 것인지 지정해서 호출.
  • 순서와 상관없이 호출하는 것이 가능.
  • parameter가 많고 대부분 기본값이 있는 함수 호출 할 때 뒤 쪽에 선언된 parameter에만 값을 전달하고 싶을 경우 유용하다.
def greet7(name, age, address = None) :
    print(name, age, address)
greet7("이순신", 32, "서울") # argument를 파라미터 순선에 맞춰서 전달. - positional argument

이순신 32 서울

greet7(name = "유관순", address = "부산", age = 25) #파라미터 = 값 - keyword argument, 순서 안맞아도 됨.

유관순 25 부산

greet7("강감찬", address = "인천", age = 30) #positional, keyword argument 같이 사용
#positional argument을 먼저 지정해야됨.

강감찬 30 인천

가변인자 (Var args) 파라미터

호출하는 쪽에서 argument로 0 ~ n개의 값을 나열해서 여러개의 값들을 전달하면 tuple이나 dictionary로 묶어서 받을 수있도록 선언하는 parameter

  • positial argument로 전달하는 것과 keyword argument로 전달되는 값을 받는 두가지 방식이 있다.

*변수명: positional argument를 개수와 상관없이 하나의 변수로 받을 수 있도록 선언하는 가변인자.

  • 전달된 값들은 tuple로 받아서 처리한다.
  • 관례적으로 변수명은 *args 를 사용한다.

**변수명: keyword argument를 개수와 상관없이 하나의 변수로 받을 수 있도록 선언하는 가변인자.

  • 전달된 값들은 dictionary로 받아서 처리한다.
  • 관례적으로 변수명은 **kwargs 를 사용한다.

하나의 함수에 가변인자는 * 하나, ** 두개짜리 각각 한개씩만 선언할 수 있다.

파라미터 선언순서
1. 기본값이 없는 파라미터
2. 기본값이 있는 파라미터
3. *args
4. **kwargs

#정수 값들을 받아서 합계를 반환.
# *변수명 - *args(보통 이렇게 함) : positional argument로 개수와 상관없이 값을 전달 받을 때 사용.
# 내부적으로 튜플로 처리 됨.
def summation(*nums) : 
    result = 0
    for v in nums :
        result += v
    print(result)
summation(1, 2, 3, 4, 5)

15

summation(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

55

summation(1, 2)

3

l = [1, 2, 3, 4, 5]
summation(*l) # *가변인자에 리스트나 튜플의 원소들을 전달 -> *리스트, *튜플

15

#**변수명 : **kwargs(보통 이렇게 씀) : keyword arguments로 개수와 상관없이 값들을 전달받을 때 사용
# 값들을 dictionary로 묶어서 전달받는다.
def print_info(**info) :
    print(info)
print_info(name = "이순신", age = 30)

{'name': '이순신', 'age': 30}

print_info(제조사 = "삼성")

{'제조사': '삼성'}

d = {"name" : "홍길동", "나이" : 20, "주소" : "서울"}
print_info(**d) #**가변인자에 딕셔너리의 값들을 전달하는 경우: **딕셔너리

{'name': '홍길동', '나이': 20, '주소': '서울'}

변수의 유효범위(scope)

지역변수 (local variable)

  • 함수안에 선언된 변수
  • 선언된 그 함수 안에서만 사용할 수 있다.

전역변수 (global variable)

  • 함수 밖에 선언 된 변수
  • 모든 함수들이 공통적으로 사용할 수 있다.
  • 하나의 함수에서 값을 변경하면 그 변한 값이 모든 함수에 영향을 주기 때문에 함부로 변경하지 않는다.
  • 함수내에서 전역변수에 값을 대입하기 위해서는 global 키워드를 이용해 사용할 것을 미리 선언해야 한다.
    - global로 선언하지 않고 함수안에서 전역변수와 이름이 같은 변수에 값을 대입하면 그 변수와 동일한 지역변수을 생성한다.
    - 조회할 경우에는 상관없다.
    - 함수에서 변수를 조회할 경우 먼저 지역변수를 찾고 없으면 전역변수를 찾는다.
#전역변수(global variable) - a, b
#사용범위(scope) - 프로그램 전지역
a = 10
b = 20
def test4() :
    #전역변수 a의 값을 변경
    global a
    a = 100
    print(a)
def test1() :
    c = 30 #test1() 함수의 지역변수(local variable). 사용볌위 : 선언된 함수 안에서만 사용가능.
    print(a) #전역변수 a 호출
    print(b) #전역변수 b 호출
    print(c)
def test2() :
    d = 40 #test2() 함수의 지역변수(local variable)
    print(a) #전역변수 a 호출
    print(b) #전역변수 b 호출
    print(d)
    #print(c) #test1() 함수의 지역변수 호출
def test3() :
    a = 50 # 지역변수 a를 정의
    print(a)
test4()

100

test3()

50

print(a)

10

test1()

10
20
30

test2()

10
20
40
NameError Traceback (most recent call last)
Cell In[107], line 1
----> 1 test2()
Cell In[105], line 15, in test2()
13 print(b) #전역변수 b 호출
14 print(d)
---> 15 print(c)
NameError: name 'c' is not defined

함수는 일급시민(First class citizen) 이다.

  • 일급 시민
  1. 변수에 대입 할 수 있다.
  2. Argument로 사용할 수 있다.
  3. 함수나 메소드의 반환값으로 사용 할 수 있다.
  • 즉 파이썬에서 함수는 일반 값(객체)으로 취급된다.
def hello() :
    print("Hello World!")
hello() #함수호출

Hello World!

v = hello #함수 자체
v()

Hello World!

v2 = v
v2()

Hello World!

f = hello() # hello() 함수를 호출해서 실행. 반환값을 변수 f에 저장.
f = hello # hello 함수 자체를 f변수에 대입.(다른 이름을 준다.)

Hello World!

#함수를 argument로 사용
def calc(func) :
    num1 = 10
    num2 = 20
    result = func(num1, num2)
    return result
#calc() 호출하는 쪽 -> caller
def plus(n1, n2) :
    return n1 + n2
calc(plus)

30

def multiply(n1, n2) :
    return n1 * n2
calc(multiply)

200

def check_length(s) :
    return len(s)
l = ["a", "abc", "aaaaaa", "aa", "dkdkdkdkdkdk"]
sorted(l, reverse = True, key = check_length)
#key = 함수
#각 원소를 key() 함수에 전달해서 실행한 결과값들을 기준으로 정렬.

['dkdkdkdkdkdk', 'aaaaaa', 'abc', 'aa', 'a']

람다식/람다표현식 (Lambda Expression)

함수를 표현식(expression)으로 정의한다.
함수를 하나의 식을 이용해서 정의할때 사용하는 표현식(구문).
값을 입력받아서 간단한 처리한 결과를 반환하는 간단한 함수를 표현식으로 정의할 수 있다.

  • 처리결과를 return 하는 구문을 하나의 명령문으로 처리할 수 있을때 람다식을 사용할 수 있다.

구문

  • lambda 매개변수[, 매개변수, ...] : 명령문(구문)

명령문(구문)은 하나의 실행문만 가능하다.
명령문(구문)이 처리한 결과를 리턴해준다.
람다식은 함수의 매개변수로 함수를 전달하는 일회성 함수를 만들때 주로 사용한다.

plus_f = lambda n1, n2 : n1 + n2
plus_f(10, 20)

30

def calc(func) :
    num1 = 10
    num2 = 20
    result = func(num1, num2)
    return result
calc(lambda n1, n2 : n1 + n2)

30

calc(lambda x, y : x * y)

200

실습

#1. 시작 정수, 끝 정수를 받아 그 사이의 모든 정수의 합을 구해서 반환하는 함수를 구현(ex: 1, 20 => 1에서 20 사이의 모든 정수의 합계)
def summation(start, stop, include_stop = False) : 
    result = 0
    if include_stop : 
        stop = stop + 1
    for v in range(start, stop) :
        result += v
    return result
summation(1, 10, True)

55

#2. 2번 문제에서 시작을 받지 않은 경우 0을, 끝 정수를 받지 않으면 10이 들어가도록 구현을 변경
def summation2(start = 0, stop = 10, include_stop = False) : 
    result = 0
    if include_stop : 
        stop = stop + 1
    for v in range(start, stop) :
        result += v
    return result
summation2(stop = 20)

190

#3. 체질량 지수는 비만도를 나타내는 지수로 키가 a미터 이고 몸무게가 b kg일때 b/(a**2) 로 구한다.
#체질량 지수가
#- 18.5 미만이면 저체중
#- 18.5이상 25미만이면 정상
#- 25이상이면 과체중
#- 30이상이면 비만으로 하는데
#몸무게와 키를 매개변수로 받아 비만인지 과체중인지 반환하는 함수를 구현하시오.
def check_bmi(tall, weight) :
    """
    bmi 지수를 이용해서 비만 여부를 알려주는 함수.
    parameter
        tall : float - 키. 단위 : 미터
        weight : float - 몸무게. 단위 : kg
    return 
        dict : bmi지수, 비만여부
    """
    bmi = weight/tall**2
    result = None
    if bmi < 18.5 :
        result = "저체중"
    elif bmi < 25 : # bmi >= 18.5 and bmi <25로 해도 됨.
        result = "정상"
    elif bmi < 30 :
        result = "과체중"
    else :
        result = "비만"
    return {"bmi" : bmi, "비만정도" : result}
check_bmi(1.8, 50)

{'bmi': 15.432098765432098, '비만정도': '저체중'}

profile
공부 & 프로젝트 & 개발 블로그

0개의 댓글