이것저것 공부기록

5. 함수, 파일, 모듈, 패키지 본문

언어/Python

5. 함수, 파일, 모듈, 패키지

채도리 2020. 5. 20. 19:23

함수

· 특정 기능을 하는 코드들을 한 곳에 모으기 위해 만들어진 기능

· 자주 사용되는 코드들을 함수로 만들어서 재사용할 수 있다.

· 전체 프로그램을 모듈로 나눌 수 있어 개발 과정이 쉬워지고, 체계적이며 유지 보수도 쉬워진다.

 

함수 정의

· 매개변수(parameter): 함수에 어떤 값을 전달할 때 사용하는 변수 (없을 수도 있고, 한 개 이상일 수도 있다.)

· 함수 이름을 정하는 규칙은 변수 이름 정하는 규칙과 같음

· 콜론과 들여쓰기 사용 주의

· 반환값이 있으면 return문을 적고, 반환값이 없으면 return문 생략 가능

def 함수이름(매개변수):
	함수 내용
    ···
    return value
def convert(F):
    C = (F-32)*5/9
    return C
   
# convert(50) 입력 시
# 10.0 출력
def hi(name):
    print('안녕하세요',name+'씨, 반갑습니다.')
    
# hi('유빈') 입력 시
# 안녕하세요 유빈씨, 반갑습니다. 출력

 

함수의 입출력

· 인수(argument): 함수에 입력(전달)하는 값(정보) / 함수를 호출하는 쪽에서 넘겨주는 값

· 매개변수(parameter): 함수에서 넘겨받아 사용되는 변수

보통 인수와 매개변수를 혼용해서 사용하기도 하나, 매개변수와 인수의 개수는 일치해야 한다. 

 

위치 기반 인수(positional argument)

· 인수가 여러개일 때 위치를 기반으로 순서를 정하는 방식

def quadratic(a, b, c):
    d = (b * b - 4 * a * c) ** 0.5 # 근의 공식
    x1 = (-b + d) / (2 * a)
    x2 = (-b - d) / (2 * a)
    return x1, x2

a, b = quadratic(1, -2, -3)
print(a) # 3.0 출력
print(b) # -1.0 출력

 

이름이 있는 인수(named argument)

· 인수에 이름을 붙여 호출하는 방식

· '인수 이름=값'으로 호출

· ex) print 함수의 end 인수

def expo(a, b, e):
	return a * (b ** e)
    
print(1, 2, 5) # 32 출력
print(1, e=3, b=2) # 8 출력

 

help() 함수

· 도움말 보기 함수

· 매개변수 명이 생각이 안 날 때도 사용 가능

 

 

위처럼 사용 가능!

 

디폴트 인수

· 함수를 정의할 때, 정의 부분에 '인수=기본값'과 같은 형식으로 디폴트 인수를 줄 수 있다.

· print() 함수의 end 인수의 디폴트 값은 '\n' 즉, print(str)print(str, end='\n')와 같다.

def repeat_string(str, n=1):
    for i in range(n):
        print(str)

repeat_string('안녕',3)
repeat_string('안녕하세요')

"""
안녕
안녕
안녕
안녕하세요
""" 출력

· 변수가 인수로 넘겨지면, 함수 안에서 값이 변경되어도 원래의 값은 변하지 않는다.

def try_to_change(number):
    print('(함수) 입력:', number)
    number = 10
    print('(함수) 변경:', number)

number = 1

print('호출 전:', number)
try_to_change(number)
print('호출 후:', number)

출력 결과

 

리스트 응용

· 리스트를 인수로 넘겨주면, 함수는 리스트의 내용을 바로 접근할 수 있다.

family = ['채유빈','채원빈','채원효']
def greet_users(name_list):
    for name in name_list:
        print('안녕하세요',name+'!')

· 앞에서 인수로 넘어온 변수를 함수 내부에서 변경했을 때 원래 값은 변화가 없지만, 리스트를 인수로 넘겨주면 함수는 리스트의 내용을 바로 수정한다.

family = ['채유빈','채원빈','채원효']
def greet_users(name_list):
    while name_list:
        name = name_list.pop()
        print('안녕하세요',name+'!')

· 리스트의 내용이 수정되는 것을 방지하려면 인수를 넘겨줄 때 리스트의 사본(copy)을 넘겨주면 된다.

  → 리스트이름[:] 

 

지역 변수, 전역 변수

· 지역 변수: 한정된 지역에서만 사용

· 전역 변수: 프로그램 전체에서 사용


2진수 → 10진수 변환

def bin2dec(bin_number):
    bin_str = str(bin_number)
    size = len(bin_str)
    i, sum = 0, 0
    while size > 0:
        if (bin_str[i] == '1'):
            sum += pow(2, size-1) # 지수 계산을 해주는 pow(x, y)함수
        size -= 1
        i += 1
    return sum

 

로또 번호 만들어주는 함수 만들기

def lotto():
    import random

    ret_val = "" # 빈 문자열 생성
    random_number = 0 
    for i in range(6): # 6번 반복
        random_number = random.randint(1, 100)
        ret_val = ret_val + " " + str(random_number) # 문자열로 변환해서 출력

    return ret_val

출력 예시

 

각 자릿수의 숫자를 전부 더한 값 출력하는 함수 만들기

# 내가 직접 짠 코드!

def sum_digits(num):
    result = 0
    num = str(num) # len 함수 사용하기 위해 문자열 형태로 변환
    for i in range (len(num)):
        result += int(num[i]) # 숫자로 연산해야 하므로 숫자 형태로 다시 변환
    return result
# 교재에 있는 예시 코드

def sum_digits(num):
    sum = 0
    temp = num
    while temp != 0:
        remainder = temp % 10 # remainder에 temp를 10으로 나눈 나머지 대입
        sum += remainder # sum에 누적하여 더하기
        temp = temp // 10 # temp에 temp를 10으로 나눈 몫 대입->마지막엔 0이 됨

    return sum

 

윤년 판단해주는 함수 만들기

· 연도가 4로 나누어 떨어지면 윤년이다.

· 4로 나누어 떨어지더라도 100으로 나누어 떨어지면 평년이다.

· 400으로 나누어 떨어지면 윤년이다.

def isLeapYear(year):
    return (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0)

출력 예시


파일

· 데이터를 컴퓨터에 영구적으로 저장하고 싶을 때 사용

· 텍스트 파일과 바이너리 파일로 나뉨

· [파일 열기] → [작업(파일에서 데이터를 읽거나 쓰기)] → [파일 닫기]

 

파일 열기

· 파일 객체 = open(파일명, 모드)

· 모드의 두 번째 글자는 파일의 타입(텍스트, 바이너리)을 명시하는 글자

· 모드는 옵션으로 명시하지 않으면 기본값은 "rt" (텍스트 파일 읽기 모드)

모드 내용
r (읽기 모드) 파일의 처음부터 읽음 (파일이 없으면 에러 발생)
w (쓰기 모드) 파일의 처음부터 씀 / 파일이 없으면 새로 만들고, 파일이 있으면 내용을 덮어 기존의 내용이 지워짐
a (추가 모드) 파일의 끝에 씀 / 기존의 내용 뒤에 덭붙임 or 파일이 없으면 새로 생성
t 텍스트 파일 / 아무것도 명시하지 않을 때의 기본값
b 바이너리 파일

 

작업 (파일에서 데이터를 읽거나 쓰기) / 파일 닫기

· 파일 읽기: 파일을 읽기 모드로 열면 반환되는 파일 객체는 리스트와 유사한 성격을 가지고 있기 때문에 for문으로 순회 가능 for line in fileA: print(line)

· 파일 쓰기: 파일 객체.write(문자열)

· 파일 닫기: 파일 객체.close()

 

 

· write() 함수는 파일에 쓴 바이트 수(14) 반환

· print() 함수는 자동으로 줄바꿈을 해주지만, write() 함수는 해주지 않으므로 직접 줄바꿈 문자(\n)를 넣어주어야 함

· 이렇게 생성된 파일은 파이썬 코딩을 하는 디렉토리에 text.txt 로 저장되어 있음

 

 

· "w" 모드로 열었더니 원래 있던 내용에 덮어써서 원래 있던 내용이 지워짐.

 

 

· "a" 모드로 쓰면 뒷부분에 추가하기 때문에 원래 있던 내용이 없어지지 않음. 위의 결과를 보니 왜 직접 줄바꿈 문자를 넣어줘야 하는지 알겠지?

 

 

· 출력 결과가 좀 이상하네?

→ "test.txt" 파일은 각 줄에 줄바꿈 문자가 이미 포함되어 있는데, print() 함수가 줄바꿈을 기본으로 해 주기 때문에 줄 바꿈이 두 번 일어나 결과가 예상과 다르게 출력된다. 그럴 땐 end='' 사용해서 줄바꿈을 사라지게 해서 출력할 수 있다.

 

 

read()

· 파일의 크기가 크지 않은 경우, read()를 인자 없이 호출하면 한 번에 전체 파일을 읽을 수 있다.

· 문자열 = 파일 객체.read([최대문자수])

· 최대문자수 인자는 대괄호 안에 있어서 옵션으로 read()와 같이 인자 없이 호출 가능

· 파일의 크기가 큰 경우에는 메모리 소비가 문제될 수 있으므로 인자 없이 호출하는 것은 작은 크기의 파일의 경우로 한정해서 사용

 

 

· 위 소스 코드에서처럼 text = inFile.read() 와 같이 호출하면 read() 함수는 결과를 하나의 문자열로 반환 / 즉, text가 반환된 문자열의 이름이고, print(text)와 같이 문자열을 출력한 것이다.

 

· 파일의 크기가 큰 경우, 한 번에 읽는 문자수를 제한하려면 read()에 인자로 최대문자수를 입력하면 된다.

    or readline() 함수 사용 문자열 = 파일 객체.readline()

 

위 예제와 동일한 파일을 5바이트씩 읽어서 반환
readline() 함수 사용 예

 

· 파일의 크기가 크지 않은 경우 readlines()를 사용하면 파일의 전체 내용을 문자열의 리스트로 읽을 수 있다.

문자열 리스트 = 파일객체.readlines()

 

 


사용자에게 텍스트 파일 이름을 입력받고, 그 파일의 각 줄에 줄번호를 붙여서 출력해주는 프로그램

filename = input("파일명: ")
aFile = open(filename, "r")
lines = aFile.readlines()
i = 1
for line in lines:
    print(i,":",line,end = '')
    i += 1
aFile.close()

 

사용자에게 텍스트 파일 이름을 입력받고, 그 파일의 글자 수와 단어 수, 그리고 줄의 갯수를 출력해주는 프로그램

filename = input("파일명: ")
aFile = open(filename, "r")

s = aFile.read() # 글자 수를 세기 위해 하나의 문자열로 읽기

print(str(len(s))+"개의 문자")

wordcnt = s.split() # 문자열을 단어 단위로 잘라 리스트로 구성 / 이 부분은 이해를 위해 넣어둠

print(str(len(s.split()))+"개의 단어")

print(str(len(s.split('\n'))-1)+"개의 줄") # split()시 개행문자('\n')를 기준으로 문자열을 나누면 줄이 됨

aFile.close()


모듈

· 모듈: 함수의 집합 / 독자적인 기능을 갖는 구성 요소

· 사용자가 정의한 함수는 모듈이라는 분리된 파일에 저장하고, 그 모듈을 메인 프로그램에서 import 해서 사용할 수 있음

· import - 다른 모듈 내의 코드에 대한 접근을 가능하게 하는 명령어

· 모듈 파일을 메인 프로그램이 있는 파일과 분리하면, 모듈의 자세한 내용을 숨기고 다른 사람들에게 공유할 수 있다.

 

 

· 모듈의 분류

모듈 기능
표준 모듈 파이썬 설치시 함께 설치되는 모듈
사용자 생성 모듈 프로그래머가 직접 작성한 모듈
서드 파티(3rd Party) 모듈 파이썬이 아닌 외부 회사나 단체에서 제공하는 모듈 (사용자가 따로 설치)

 

 

· import 방식

방법 표현
모듈 import import 모듈명
모듈 내의 특정 함수만 import -1 from 모듈 import 변수 또는 함수
모듈 내의 특정 함수만 import -2 from 모듈 import 함수1, 함수2, ···
모듈 내의 특정 함수만 import -3 from 모듈 import * (사용 지양)

3번 - 코드가 복잡해지고 모듈의 수가 많아지면 어떤 모듈 또는 어떤 변수, 함수를 불러오고 있는지 파악하기 힘들어지기 때문에 웬만하면 사용하지 말 것을 권장한다.

 

as - 모듈명 줄여서 사용

· import calculator as C (위의 모듈 import 방법에서 사용)

· from my_package import calculator as C (패키지와 함께 사용)


패키지

· 패키지: 여러 모듈을 모아 놓은 것으로, 폴더의 형태로 나타남

· from 패키지 import 함수

· 모듈을 주제별로 분리할 때 주로 사용

 

 


피보나치 수열

· fibo_py 로 저장

def fib(n):
	a, b = 0, 1
    while a < n:
    	print(a, end=' ')
        a, b = b, a+b
    print()

'언어 > Python' 카테고리의 다른 글

[소창] 10주차 응용 실습 복습  (0) 2020.05.31
4. 리스트, 튜플, 딕셔너리  (0) 2020.05.19
3. 반복문  (0) 2020.05.19
2. 조건문  (0) 2020.05.19
1. 변수, 숫자, 문자열  (0) 2020.05.18