본문 바로가기

나도코딩 파이썬

[나도코딩 파이썬기초(5)] 함수, 전달값과 반환값(return), 기본값, 키워드값, 가변인자, 지역변수 전역변수

함수

def 함수명() :

       함수 실행내용

 

이런식으로 함수를 만들 수 있다.

함수는 선언하기전에는 실행되지 않는다.

 

함수의 전달값과 반환값

위에서 선언한 함수는 () <- 전달값이 없다.

전달값은 함수의 괄호사이에 넣으면 된다.

함수 Return 부분이 잘 이해가 안됐는데,

 

balance = deposit(balance, 1000)

이런식으로 변수를 함수로 선언해주면

변수 자체가 함수의 반환값(return)을 의미하게 된다.

사실 이것도 100% 이해된 것은 아니지만 일단 이렇게 이해하고 넘어가본다.

 

함수 안에 if 문 넣기

반복문 안에 넣는것처럼 넣어주면 된다.

 

위에서와 마찬가지로 변수 = 함수(전달값)으로 호출하면

return값이 반환된다.

 

전달값이 아닌 값도 반환할 수 있다.

withdraw_night라는 새로운 함수를 생성해서

commision = 100 이라는 새로운 변수를 넣어준다.

 

이 값은 전달값은 아니지만

반환할 때 반환값에 넣어줄 수 있다.

 

이 개념을...

반환하면서 새로운 변수들을 생성한다고 생각하면 이해하기 쉬울 것 같다.

 

withdraw_night(balance,500) ... 이렇게 함수를 호출하면

commision = 100, balance = balance - money - commission 이런식으로

각각의 변수를 생성해 format()에서도 불러올 수 있다고 이해하자.

 

함수의 기본값

여기서 \t 은 탭을 쳐서 띄어쓰기를 준 효과를,

\ 후 엔터를 친 것은 그냥 코드 상의 줄을 구분한 것일 뿐 실제로는 한 줄로 출력된다.

즉, 코드가 너무 길어져 가독성이 떨어질 때 구분하는 것이다.

 

전달값에 '기본값'을 넣어주면

특정 값을 입력하지 않는 경우에는 자동으로 기본값이 전달값으로 입력된다.

 

키워드값

전달값 순서대로 입력해도 되지만

각각의 키워드를 입력하면 순서가 바뀌어도 상관없다.

 

아래 예시처럼

main_lang="자바"는 원래 가장 마지막 전달값이지만

제일 앞에 키워드를 직접 입력해주는 경우에는

순서가 상관없다는 의미이다.

 

가변인자

줄바꿈 end = " "

 

위에서는 \ (역슬래시)를 사용해서 코드 상의 줄을 구분하고 실제로는 한 줄로 표기되는 법을 배웠다.

여기서 줄바꿈 end = " "는, 다음에 어떤 함수를 실행해도 이어서 출력되게 해준다.

 

역슬래시는 단순 줄구분이고 end는 다음 구문을 이어서 출력해준다는 점이 다르다.

 

전달값에 lang 1 부터 5까지 있는데,

이 전달값에 새로운 인자를 추가하려면 함수 자체를 바꿔야하고

인자가 없는 경우에는 마지막 줄처럼 "" 이렇게 공란으로 둬야하는 번거로움이 있다.

 

이 때 가변인자를 사용한다.

*language ... 가변인자 앞에 *을 넣어 표기한다.

 

for lang in language: ... for문으로 여러개 있는 경우 반복해서 출력하도록한다.

      print(lang, end=" ") ... lang 은 내가 함수 안에 age 다음으로 입력하는 인자들을 의미한다.

 

=> 이부분이 좀 헷갈리긴 하는데 for 문을 자주 써보며 이해하기.

=> 변수를 별도로 선언하지 않고 내가 입력하는 값이 가변인자의 값에 들어간다고 이해하기.

 

print() ... end = " " 으로 구분했으므로 다음 함수를 실행했을 때는 줄바꿈이 되도록 print() 를 입력해준다.

 

 

지역변수와 전역변수

지역변수 - 함수 내에서만 사용되는 변수

전역변수 - 프로그램 내에서 어디서든 사용되는 변수

 

gun 이라는 함수는 할당이 되기 전 (before assignment) 사용되었다.(referenced)

 

함수 내의 gun,

즉 지역변수 gun은 초기화가 안되었기 때문에 사용될 수 없다는 뜻.

함수 내부에서 gun이라는 변수를 선언해주어야 한다는 뜻.

 

함수 내에서 gun = 20으로 변수를 선언해주고,

함수의 전달값을 2로 호출하면 20-2 = 18로 잘 출력이 된다.

 

그런데 함수를 호출하지 않고

gun이라는 변수를 format으로 불러오면 전역변수 gun, 10으로 출력된다.

 

이 때, 전역변수를 함수 내로 불러오기위해

global (전역변수) 를 입력해주면

전역변수를 함수 내에서 사용할 수 있고,

 

함수로 인해 전역변수가 변경되는 경우

이 값이 전역변수에 반영된다.

 

일반적으로 전역변수를 사용하진않고

함수 내에서 전달값, 반환값을 주로 사용한다.

 

전역변수를 많이 쓰면 코드관리가 어려워져 추천되진않는다.

 

def checkpoint_ret(gun, soldiers):

      gun = gun - soldiers

 

=> 이렇게 선언해도 gun은 지역변수이기때문에

실제 전역변수 Gun에 반영되지 않는다.

 

=> return gun으로 반환해주면,

함수 외부로 보낼 수 있게된다.

 

gun = checkpoint_ret(gun,2)

이런식으로 다시 호출해주면 

함수에서 반환되는 값을 전역변수에 저장해준다.

 

퀴즈

 

1트!!
from cgi import print_directory
from math import floor


def std_weight(height, gender):
    if gender == "남자":
        return height * height * 22 * (0.1**4)
    elif gender == "여자":
        return height * height * 21 * (0.1**4)

print(round(float(std_weight(175,"남자")),2))

# standard = float(std_weight(175,"남자")) * (0.1^4)

# print("키{0} {1}의 표준체중은 {2}입니다.".format(175,"남자",round(float(std_weight(175,"남자")))*0.1^4,2))

# 이후 문장은 한번에 넣으려니까 자꾸 타입이 안맞아서 에러가 난다고해서...

소수점 둘째자리까지 만드는 것만 print해보니 잘 나온다.

 

from cgi import print_directory
from math import floor


def std_weight(height, gender):
    if gender == "남자":
        return "키 {0}인 {1}의 표준체중은 {2}kg 입니다".format(height,gender,
            round(float(height * height * 22 * (0.1**4)),2))
    elif gender == "여자":
        return "키 {0}인 {1}의 표준체중은 {2}kg 입니다".format(height,gender,
        round(float(height * height * 21 * (0.1**4)),2))

print(std_weight(175,"남자"))

원하는 결과가 나오기는 하는데 너무 코드가 조잡하다.

특히 return 부분이 너무 복잡해서 좀 정리하고 싶다.

 

근데 그러려면 height를 전역변수로 꺼내야 하는데,

아니면 일단 return 밖으로 print 구문을 한번 꺼내본다.

 

정답

정답에서는 height, gender를 모두 전역변수로 빼주고

함수를 weight 라는 변수로 호출해준다.

 

print 구문이 한결 간결해졌다.