VO(Value object) 또는 DTO(Data Trangfer Object)

데이터를 교환하는 객체

계층간 데이터 교환을 위해 사용하는 객체

DB에서 데이터를 얻어 Service나 Controller 등으로 보낼 때 사용하는 객체

 

 

DAO(Database Access object)

데이터에 접근하는 객체

DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트.

DB를 대신하여 리스트 사용할 수도 있다.

 

SELECT/INSERT/UPDATE/DELETE 등 데이터 처리가 주 목적

 

 

Service(비즈니스 로직 구현) 

사용자에 제공할 기능을 구현하는 클래스

 

DAO와 Service가 비슷한 기능으로 보이지만 DAO는 CRUD작업을 하나씩 분할해 놓은 것이다.'

사용자가 글을 작성하거나 수정하는 것과 동시에 페이지가 이동한다면 update, select가 작동하기 때문에

여러 dao를 service안에 조립하는 로직을 갖게된다.

 

 

그럼 예제를 하나 다뤄보자.

이름, 전화, 주소를 저장하는 주소록을 만들어보자.

#이름, 전화, 주소
#VO(Value object) / DTO(Data Trangfer Object)
class Member:
    def __init__(self, name='', tel='', address=''):
        self.name = name
        self.tel = tel
        self.address = address

    def printMember(self):
        print('name:' , self.name)
        print('tel:' , self.tel)
        print('address:' , self.address)
        print()

#DAO(Database Access object)
class MemDao:   #저장소 관련 작업만 담당
    def __init__(self):
        self.datas = []

    def insert(self, m):
        self.datas.append(m)

    def select(self, name):
        for i in self.datas:
            if i.name == name:
                return  i   #검색된 객체의 참조값 반환. 객체에 다이렉트로 접근

    def selectAll(self):
        return self.datas

    #def update(self,m):   #수정할사람의 이름, 새전화, 새주소

    def delete(self,m):
        self.datas.remove(m)

#Service
class MemService:
    def __init__(self):
        self.dao = MemDao()

    def addMember(self):
        name = input('name:')
        tel = input('tel:')
        address = input('adress:')
        m = Member(name, tel, address)
        self.dao.insert(m)

    def printMember(self):
        name = input('search name:')
        m = self.dao.select(name)
        if m == None:
            print('없는 이름')
        else:
            m.printMember()

    def printAll(self):
        datas = self.dao.selectAll()
        for i in datas:
            i.printMember()

    def editMember(self):
        name = input('수정할 사람 이름:')
        m = self.dao.select(name)
        if m == None:
            print('없는 이름')

        else:
            m.tel = input('new tel:')
            m.address = input('new address:')

    def delMember(self):
        name = input('삭제할 사람 이름:')
        m = self.dao.select(name)
        if m == None:
            print('없는 이름')
        else:
            self.dao.delete(m)

class Menu:
    def __init__(self):
        self.service = MemService()

    def run(self):
        while True:
            menu=int(input('1.등록 2.검색 3.수정 4.삭제 5.전체출력 6.종료'))
            if menu == 1:
                self.service.addMember()
            if menu == 2:
                self.service.printMember()
            if menu == 3:
                self.service.editMember()
            if menu == 4:
                self.service.delMember()
            if menu == 5:
                self.service.printAll()
            if menu == 6:
                break


def main():
    m= Menu()
    m.run()

main()

 

Q. (레벨1) 성적처리프로그램을 만드시오. (국,영,수,총합,평균을 출력해야합니다)

 

class Member:
    def __init__(self,num,name,kor,eng,math):
        self.num = num
        self.name = name
        self.kor = kor
        self.eng = eng
        self.math = math

    def Total(self):
        self.total = self.kor+self.eng+self.math
        print(self.total, ' ', end='')

    def Avg(self):
        self.avg = self.total/3
        print(self.avg)

    def printData(self):
        print('번호 이름 국어 영어 수학 총점 평균')
        print(self.num,self.name,self.kor,self.eng,self.math,' ', end='')
        self.Total(), self.Avg()


def main():
    c1 = Member('1','홍길동',50,60,70)
    c1.printData()

    c2 = Member('2','김철수', 85,98,32)
    c2.printData()

    c2 = Member('3','박혁거', 82,45,95)
    c2.printData()

    persons=[]
    for i in range(0, 3):
        persons.append(Member())

main()



class Member:
    def __init__(self,num,name,kor,eng,math):
        self.num = num
        self.name = name
        self.kor = kor
        self.eng = eng
        self.math = math

    def Total(self):
        self.total = self.kor+self.eng+self.math
        print(self.total, ' ', end='')

    def Avg(self):
        self.avg = self.total/3
        print(self.avg)

    def printData(self):
        print('번호 이름 국어 영어 수학 총점 평균')
        print(self.num,self.name,self.kor,self.eng,self.math,' ', end='')
        self.Total(), self.Avg()


def main():
    c1 = Member('1','홍길동',50,60,70)
    c1.printData()

    c2 = Member('2','김철수', 85,98,32)
    c2.printData()

    c2 = Member('3','박혁거', 82,45,95)
    c2.printData()

    persons=[]
    for i in range(0, 3):
        persons.append(Member())

main()

우선 전체적으로 출력을 해보기 위해 뚱땅뚱땅 코드를 만들어보았다.

출력결과가 그럴듯하게 보이기 위해 print를 대충 얹어쓴느낌..?

 

이 부분이 마음에 들지 않지만 내가 할 수 있는 최선이었다... 

 

 

 

Q. (단계2)

class Student:
    def __init__(self,name='',num=0,score=[]):
        self.name = name
        self.num = num
        self.score = score    #국영수총평

    def calc(self):
        for i in range(0, 3):
            self.score[3] += self.score[i]

        self.score[4] = self.score[3]/3

    def printInfo(self):
        print(self.name, end='\t')
        print(self.num, end='\t')
        for i in self.score:
            print(i, end='\t')
        print()

def main():
    c1=Student('aaa', 1, [67,87,56,0,0])
    c1.calc()
    c1.printInfo()

    c2=Student('bbb', 2, [65,11,75,0,0])
    c2.calc()
    c2.printInfo()

    c3=Student('ccc', 1, [87,21,64,0,0])
    c3.calc()
    c3.printInfo()


main()

기능을 조금 더 세분화시켰고, for문으로 프린트하는 값을 간결하게 표현했다.

성적처리에서 가장 중요한 부분은 총점과 평균을 연산해야하는 부분이기 때문에 점수부분들은 score=[]로 리스트에 담아버렸다!

 

 

 

Q. (단계 3)  ★★★

class Score:   #1명의 점수만 가지고 다루는 클래스
    def __init__(self,kor,eng,math):
        self.kor = kor
        self.eng = eng
        self.math = math
        self.total = self.kor + self.eng + self.math
        self.avg = self.total / 3


    def printScore(self):
        print(self.kor, end='\t')
        print(self.eng, end='\t')
        print(self.math, end='\t')
        print(self.total, end='\t')
        print(self.avg, end='\t')
        print()

class Student:   #1학생의 정보(score포함) 갖는 클래스
    def __init__(self,name,num, score):
        self.name = name
        self.num = num
        self.score = score   #Score객체. 포함관계

    def printMember(self):
        print(self.name, end='\t')
        print(self.num, end='\t')
        self.score.printScore()



def main():
    sc1 = Score(85, 64, 21)
    s1 = Student('aaa', 1, sc1)
    s1.printMember()

    s2 = Student('bbb', 2, Score(45,61,94))
    s2.printMember()


main()

객체지향적인 관점에서 볼 때, 함수들을 세분화시켜서 나누는 것이 유리한 것같다.

그래서 1명의 점수만 입력받는 클래스와 1명의 정보를 입력받는 클래스로 나누어서 짜준 뒤 확장하게 되면 메인함수가 더 간략해진다. (개인적으로 메인이 깔끔한 것이 마음 편하다)

 

코드를 짤 때 한번에 퉁쳐서 짜보려 하지 말고 1명 단위에서 다수의 단위로 넘어가게끔 연습해보자.

'파이썬이 제일 쉽다면서요' 카테고리의 다른 글

python #정적멤버와 정적메소드  (0) 2021.06.10
python #VO, DAO, Service  (0) 2021.06.10
python #연습문제  (0) 2021.06.09
python #객체지향프로그래밍  (0) 2021.06.09
python #예외처리  (0) 2021.06.09

Q. 클래스를 이용하여 주소록 만들기

class Member:
    def __init__(self,id,pwd,name,email):
        self.id = id
        self.pwd = pwd
        self.name = name
        self.email = email

    def printMember(self):
        print('id:',self.id)
        print('pwd:',self.pwd)
        print('name:',self.name)
        print('email:',self.email)


def main():
    c1 = Member('hodu', '121', 'YB', 'hodorotorl@gmail.com')
    c1.printMember()

    c2 = Member(name='Yb', pwd='1212312', id='박호두', email='hodorotorl')
    c2.printMember()

    c3= c2
    c3.name = '가나다'
    c3.email = 'rksksk@naver.com'
    c3.printMember()
    c2.printMember()
    
main()

 

 

 

Q. 다양한 형태의 멤버 변수 활용

class Point:
    def __init__(self, x=0, y=0):
        self.x =x
        self.y =y
    def printPoint(self):
        print('좌표:(',self.x,',',self.y,')')

class Test:
    def __init__(self):
        self.num =0
        self.s=''
        self.arr=[]
        self.point =None   #객체. 포함관계:클래스타입의 멤버변수 / 관계(포함관계-has a, 상속관계-is a)

    def printData(self):
        print('num:', self.num)
        print('s:', self.s)
        print('arr:', self.arr)
        self.point.printPoint()

def main():
    t1 = Test()   #객체 생성
    t1.num = 10
    t1.s = 'hello class'
    t1.arr.append(1)
    t1.arr.append(2)
    t1.arr.append(3)
    t1.point = Point(3,4)   #개중요!!
    t1.printData()

main()

 

Point로 좌표 찍는 것이 활용도가 높으니 예제로 많이 다뤄두자.

 

객체 지향 프로그래밍(OPP)

드디어! 나왔다. '객체 지향 프로그래밍'


순차적프로그래밍은 시간의 흐름 순서대로 코드를 짰다면 객체 지향 프로그래밍은 객체를 중심으로 개발
객체를 정의하고 객체와 객체 사이의 관계를 정의하는 방식으로 프래그래밍 한다.

객체란, 세상을 프로그램으로 모델링할 때 모델링의 대상이 되는 사람이나 사물. 즉 샘플을 의미한다.
객체를 샘플링하여 객체란 타입을 정의하면 관련있는 정보를 묶어서 하나의 변수에 담아 간단하게 표현할 수 있다.

(일반 변수는 값을 하나 밖에 못 담지만 객체는 관련 정보 여러가지를 담을 수 있다는 것이 장점이다! 물론..그래서 헤깔리지..)

예를들어 ATM의 출금과정을 코딩한다고 해보자.


1. 카드를 넣는다.

2. 카드 비밀번호 입력

   2-1. 비밀번호가 맞다?

        3. 출금액 입력

        4. 카드와 연결된 계좌 정보를 추출

   2-2. 비밀번호가 틀리다?

        3. 저리가세요~

 

그럼 위의 간단한 알고리즘에서 우리가 객체라고 볼 수 있는 것이 뭐가 있을까?

<카드객체>
카드번호
비밀번호
카드명의자
카드사
연결계좌
<계좌객체>
계좌번호
비밀번호
명의자
은행명

오호. 이렇게 간략한 구상이 먼저 이루어지면 OPP도 문제없다!! (글쎄..)

자, 그럼 가장 먼저 클래스를 정의해보자.

class 클래스명:
	def __init__(self): #생성자. 객체 초기화. 객체의 멤버변수(클래스 소속의 변수) 정의.	
		멤버변수 정의
	def 기능(self):
		실행문

 

ATM 출금을 예로 들면 
출금 금액은 변수
카드정보 는 Class Card를 정의해서
카드번호, 카드명의자, 카드비밀번호 와 같은 값들을 담으려면 클래스 안에 변수들이 멤버변수가 된다.

class Card:   #Card 라는 이름의 타입을 정의함. 이 타입의 변수는 카드 1개의 정보를 담을 수 있다.

    #생성자
    def __init__(self):    #첫번째 파라미터는 현재 객체의 참조값을 받음.
        self.number = ''   #카드번호     #멤버변수표현은 앞에 self.변수이름
        self.owner = ''    #카드명의자
        self.pwd = ''      #카드비번
        self.comp = ''     #카드사
   

    #메소드. 멤버함수
    def printCard(self):   #self:현재 객체. 객체 생성전이기 때문에 객체 이름 모름.
        print('number:', self.number)
        print('owner:', self.owner)
        print('pwd:', self.pwd)
        print('comp:', self.comp)

def main():
    x = 10    #일반변수 정의 변수이름=값

    #객체(클래스로 만든변수)는 바로 값을 할당할 수 없고 먼저 생성해야함. 
    #생성하는 방법은 생성자 호출. 생성사 호출은 클래스 이름.
    
    c1 = Card()    #캡슐화
    c1.number='123-4567-8901'      #  .(멤버접근연산자)
    c1.owner = '홍길동'
    c1.pwd = '111'
    c1.comp = '신한'
    c1.printCard()


main()

 

 

위의 코드를 좀 더 심플하게 짜보면

 

class Card:   #Card 라는 이름의 타입을 정의함. 이 타입의 변수는 카드 1개의 정보를 담을 수 있다.

    #생성자
    def __init__(self, number, owner, pwd, comp):
        self.number = number   #카드번호     #멤버변수표현은 앞에 self.변수이름
        self.owner = owner    #카드명의자
        self.pwd = pwd     #카드비번
        self.comp = comp


    #메소드. 멤버함수
    def printCard(self):   #self:현재 객체. 객체 생성전이기 때문에 객체 이름 모름.
        print('number:', self.number)
        print('owner:', self.owner)
        print('pwd:', self.pwd)
        print('comp:', self.comp)

def main():
    c1 = Card('123-4567-8901','홍길동','111','신한')
    c1.printCard()

    c2 = Card('2564-462-645','김철수','123123','우리')
    c2.printCard()

main()

따라~

'파이썬이 제일 쉽다면서요' 카테고리의 다른 글

python # 연습문제. 성적처리프로그램  (0) 2021.06.10
python #연습문제  (0) 2021.06.09
python #예외처리  (0) 2021.06.09
python #연습문제. 주소록 만들기  (1) 2021.06.08
phthon #입출력  (0) 2021.06.08
예외처리

어떤 언어든 코드를 짜다보면 에러가 발생한다.

컴파일 에러일때는 문법상의 문제이기때문에 컴파일러가 친절하게 알려주는 오류부분을 찾아 수정하면 되지만 런타임시 문제가 발생한다면...? 노답이 되버린다.

이렇게 예외가 발생한 상황에서는 파이썬 시스템이 예외 객체를 생성해서 던져버리고는 뻗어버린다.

그래서 우리는 미리 예외처리를 해놓고 프로그램이 중단되지 않고 끝까지 진행되도록 하자!

사실 파이썬에서 예외처리가 필수는 아니지만 프로그램의 안정성을 높이기 위해서 사용하는 것이 좋다.

try:
	예외발생 예측 #예를들면 res 3/0
except 예외명:
	예외처리작성
def main():
    print('프로그램 시작')
    try:
        res = 3/0
        print('test1')
        res = 'aaa' + 1
        print('test2')
        arr[3]=4
    except ZeroDivisionError:
        print('0으로 나눌 수 없음')
    except TypeError as e:   #파이썬 내장된 에러메세지를 출력
        print(e)
    except Exception as e:  # 모든 예외를 포함
        print(e)
    except:      #예측못한 에러도 있을 수 있으니 따로 뭘 지정하지 않음.
        print('모든 에러')
    else:
        print('예외가 발생하지 않음')  #else는 써도 되고 안써도 되고
    finally:
        print('예외가 발생하건 정상실행되건 종료전 항상 실행되는 블록')

    print('프로그램 종료')

main()

out)

 

 

사용자정의에 의한 예외처리

 

아니면 파이썬에 정의되지 않은 예외 클래스를 쓰고 싶을 때 직접 만들수 있다.

class 예외클래스명(Exception):
	def __init__(self, msg): #생성자, 객체 초기화 함수. 사용할 에러 메세지 할당
	self.msg=msg

 

파이썬이 인지하지 못하는 예외를 직접 발생키시고 싶을 때 사용할 수 있는 구문이 있는데

raise 예외객체 생성

raise는 파이썬에 있는 에러를 사용해도 된다.  raise TypeError('에러 메시지') 처럼.

 



class NumError(Exception):    #Exception을 상속받음
    def __init__(self, msg):   #생성자. 객체 초기화 함수
        self.msg = msg


def f1(num):    #5이하의 숫자만 가능. 5보다 큰 숫자를 받으면 심각한 발생
    if num>5:
        raise NumError('num은 5보다 작거나 같아야 함')   #raise 예외객체 : 예외 발생 구문

    print(num)

def f2(num):
    if not isinstance(num, int) :     #타입을 확인하는 함수.(참/거짓)
        raise TypeError('num은 int이어야 함')
    return num+10

def main():
    try:
        f1(10)
        f2('aaa')
    except NumError as e:
        print(e.msg)
    except TypeError as e:
        print(e)

main()

위의 코드를 해석해보면

함수에서 예외가 발생하면 먼저 그 함수 안에서 예외처리 코드를 찾고 있으면 그것을 실행,
없으면 이 함수를 호출한 위치에서 예외처리 구문을 또 찾고 있으면 그 예외처리 구문을 실행한다.

없으면...결국 파이썬은 다운되버린다!

'파이썬이 제일 쉽다면서요' 카테고리의 다른 글

python #연습문제  (0) 2021.06.09
python #객체지향프로그래밍  (0) 2021.06.09
python #연습문제. 주소록 만들기  (1) 2021.06.08
phthon #입출력  (0) 2021.06.08
python #재귀함수  (0) 2021.06.07

Q. 이름, 전화번호, 주소를 입력받아 주소록을 만들자.

members = []
titles = ['name:', 'tel:', 'address:']

#등록함수
def addMember():
    m = [0,0,0]
    print('새 멤버 등록')
    for i in range(0, len(m)):
        if i == 0:
            while True:
                m[i] = input(titles[i])
                res = getByName(m[i])
                if res==None:
                    break
        else:
            m[i] = input(titles[i])

    members.append(m)

def getByName(name):
    for idx, i in enumerate(members):
        if name == i[0]:
            return idx, i  #튜플로 반환(idx, i) => res[0]:idx, res[1]:i

def printMember():
    print('멤버 검색')
    name = input('검색할 이름:')
    res = getByName(name)
    if res == None:
        print('not found name')
    else:
        i = res[1]
        cnt = 0
        for j in i:
            print(titles[cnt],j)
            cnt += 1
        print('----------')

def printAll():
    print('모든 멤버')
    for i in members:
        cnt = 0
        for j in i:
            print(titles[cnt], j)
            cnt += 1
        print('----------')

def editMember():
    print('멤버 정보 수정')
    name = input('수정할 이름:')
    res = getByName(name)
    if res == None:
        print('not found name')
    else:
        i = res[1]
        i[1] = input('new tel:')
        i[2] = input('new address:')

def delMember():
    print('멤버 정보 삭제')
    name = input('삭제할 이름:')
    res = getByName(name)
    if res == None:
        print('not found name')
    else:
        del members[res[0]]


def main():
    while True:
        menu = input('1.등록 2.검색 3.수정 4.삭제 5.전체출력 6.종료')
        if menu == '1':
            addMember()
        elif menu =='2':
            printMember()
        elif menu == '3':
            editMember()
        elif menu == '4':
            delMember()
        elif menu == '5':
            printAll()
        elif menu == '6':
            break

main()

out)

'파이썬이 제일 쉽다면서요' 카테고리의 다른 글

python #객체지향프로그래밍  (0) 2021.06.09
python #예외처리  (0) 2021.06.09
phthon #입출력  (0) 2021.06.08
python #재귀함수  (0) 2021.06.07
python #연습문제. Email등록과 찾기  (0) 2021.06.07

입력 : 데이터가 외부에서 프로그램으로 들어오면 입력(키보드,마우스 등),
출력 : 데이터가 프로그램에서 외부로 흘러나감(모니터, 프린터 등)
입출력 흐름을 스트림이라고 함(입력 스트림, 출력스트림)
스트림:데이터의 흐름을 소프트웨어로 구현한 것


표준입출력(stdio)

기본 제공
sys.stdin:표준입력
sys.stdout:표준출력
sys.stderr:표준에러

 

import sys

def main():
    sin = sys.stdin  #키보드 입력 스트림.
    sout = sys.stdout  #콘솔 출력 스트림
    serr = sys.stderr   #콘솔에 에러 출력 스트림

    num = sout.write('문자를 입력하시오\n')  #write():출력 스트림에 출력
    sout.write(str(num)+' 개의 문자 출력됨\n')
    s=sin.read(5)     #read(size):입력 스트림에서 size만큼 읽음
    sout.write('입력받은 값:'+s+'\n')
    sout.write('한줄을 입력하시오\n')
    sin.readline()
    s = sin.readline()
    sout.write('입력받은 값:'+ s +'\n')
    serr.write('에러 메시지')

main()

out)

 

'파이썬이 제일 쉽다면서요' 카테고리의 다른 글

python #예외처리  (0) 2021.06.09
python #연습문제. 주소록 만들기  (1) 2021.06.08
python #재귀함수  (0) 2021.06.07
python #연습문제. Email등록과 찾기  (0) 2021.06.07
python #인자  (0) 2021.06.07
재귀함수

재귀함수는 자신을 호출하는 함수다. 반복동작을 짧게 구현할 수 있는 장점이 있지만 스택 사용량이 확 늘어나서 스택 오버플로우 문제 발생을 야기한다. 대부분 재귀는 루프로 대체 가능하기 때문에 루프로 대체하는 것이 좋다.

 

 

# 5! = 5*4*3*2*1

def fact1(num):
    if num == 1:     #끝나는 조건이 가장중요!
        return 1
    else:
        return num * fact1(num-1)

def fact2(num):
    res = 1
    for i in range(1,num+1):
        res *= i
    return res

def main():
    res = fact1(4)
    print('4!=', res)

    res = fact2(4)
    print('4!=', res)


main()

out)

 

 

Q. 피보나치수열 100항을 출력하라.

 

#재귀함수이용

def fibo1(num):
    if num <= 2:
        return 1
    else:
        return fibo1(num-1)+fibo1(num-2)
        
        
def main():
   
    for i in range(1, 101):
        print(fibo1(i))
#루프 이용해서
def fibo2(cnt):
    i, j, k = 1, 1, 0
    for x in range(1, cnt+1):
        if x<3:
            print(1, end='\t')
        else:
            k= i + j
            print(k, end='\t')
            i = j
            j = k
            
def main():

    fibo2(100)   
#리스트
def fibo3(cnt):
    res =[1,1]
    for i in range(2, cnt+1):
        res.append(res[i-1] + res[i-2])
    return res
    

def main():
    res = fibo3(100)    
    print(res)​

out)

모두 다 피보나치수열을 출력하지만 재귀함수는 출력하는 속도가 점차 느려진다.

그래서 재귀함수보다는 루프문으로 코드를 작성하는 것을 권장한다.

'파이썬이 제일 쉽다면서요' 카테고리의 다른 글

python #연습문제. 주소록 만들기  (1) 2021.06.08
phthon #입출력  (0) 2021.06.08
python #연습문제. Email등록과 찾기  (0) 2021.06.07
python #인자  (0) 2021.06.07
python #immutable과 mutable  (0) 2021.06.07
#이메일찾기

emails=[]

def addEmail():   #등록하는 함수. 중복혀용 안됨. 이메일 입력받아 리스트 추가
    while True:
        email = input('이메일을 입력하시오.')
        res = searchEmail(email)
        if res == None:
            break
        else:
            print('중복된 이메일입니다. 다시 입력하시오')
    emails.append(email)


def searchEmail(s_email):  #파라메터로 검색할 이메일을 받아서 emails리스트에서 검색. 
						   #있으면 인덱스, 없으면 아무값도 반환안함.
    for idx, i in enumerate(emails):
        if i == s_email:
            return idx

def printEmail():
    email = input('검색할 이메일을 입력:')
    idx = searchEmail(email)
    if idx == None:
        print('없는 이메일')
    else:
        print('이메일있음 /', emails[idx])

def printAll():
    print('등록된 이메일')
    for i in emails:
        print(i)

def main():
    while True:
        menu = input('1.등록 2.검색 3.전체출력 4.종료')
        if menu == '1':
            addEmail()
        elif menu =='2':
            printEmail()
        elif menu == '3':
            printAll()
        elif menu == '4':
            break

main()

 

 

'파이썬이 제일 쉽다면서요' 카테고리의 다른 글

phthon #입출력  (0) 2021.06.08
python #재귀함수  (0) 2021.06.07
python #인자  (0) 2021.06.07
python #immutable과 mutable  (0) 2021.06.07
python #연습문제. 다마고치게임  (0) 2021.06.07
요구인자

인자는 간단하게 함수에 데이터를 전달하는 방법이다. 

밑의 예제에서 f1(n, t, a) 는 함수의 실행을 위해 3개의 인자를 전달하라는 것이다.

여기서 중요한건 각각의 순서(위치)가 중요하다.

n이 제일 먼저 쓰여있기 때문에 가장먼저 호출해야할 값은 name.

그 다음은 t가 불러올 tel, 마지막으로는 a가 불러오는 age이다.

만약 f1(a, n, t)가 된다면 생각한 함수값들이 뒤 엉켜 버리게 된다! 왜냐, 호출의 순서가 중요하기 때문!

f1(a, n, t) 에서는 가장먼저 age를 불러오게 되고 출력된 name은 12라는 엉뚱한 값을 같게된다.

 

def f1(name, tel, age):
    print('name:', name)
    print('tel:', tel)
    print('10년 후 age:', age+10)

def main():
    n = 'aaa'
    t = '1234'
    a = 12

    f1(n, t, a)
    f1(a, n, t)    #들어가는 값이 엉킴

main()

out)

 

 

keyword argument

그럼 위와 같은 오류를 방지하기 위해 우리가 할 수 있는 것은 무엇일까?

바로 키워드인자를 이용하여 아예 값을 박제시키는 것!

 

def f1(name, tel, age=5):  #age=5: 아규먼트 기본값
    print('name:', name)
    print('tel:', tel)
    print('10년 후 age:', age+10)

def main():
    n = 'aaa'
    t = '1234'
    a = 12

    f1(tel=t, age=a, name=n)   #키워드 인자를 이용하면 순서 엉켜도 출력 제대로
    f1(n, t)

main()

out)

키워드 인자를 이용하여 오류도 엉킴도 없이 완벽한 출력이 가능하다!

 

 

가변인자

임의의 개수의 인자를 받는 함수를 가리켜 가변 인자를 사용한다고 표현한다.

표현방법은 def 함수명(*변수) 이처럼 변수 앞에 *을 붙여서 표현하면, 입력된 변수값을 튜플로 받아온다고 생각하는 것이다. 입력할 수 있는 튜플의 갯수가 제약이 없다는 것이 특이점이다.

 

def f1(*x):  #가변인자. 튜플로 받아옴.
    print('함수시작')
    for i in x:
        print(i)
    print('함수끝')


def main():
    f1()
    f1('aaa', 'bbb')
    f1('ccc', 'ddd', 'eee', 'fff')   #갯수의 제한이 없음


main()

out)

 

그럼 가변인자를 이용하여 변수들의 합을 구하는 함수를 만들어보면?

 


def add(*nums):  #가변인자. 튜플로 받아옴.

    s = 0
    for i in nums:
        s +=i
    return s


def main():

    s = add(1,2,3)
    print('add(1,2,3):', s)
    s = add(1,2,3,4,5)
    print('add(1,2,3,4,5):', s)

main()

out)

따라~~

+ Recent posts