이것저것 공부기록
5. 함수, 파일, 모듈, 패키지 본문
함수
· 특정 기능을 하는 코드들을 한 곳에 모으기 위해 만들어진 기능
· 자주 사용되는 코드들을 함수로 만들어서 재사용할 수 있다.
· 전체 프로그램을 모듈로 나눌 수 있어 개발 과정이 쉬워지고, 체계적이며 유지 보수도 쉬워진다.
함수 정의
· 매개변수(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()


· 파일의 크기가 크지 않은 경우 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 |