반응형

스레드란 ?

 

- 1개의 프로세스가 1개의 일을 하지만,

스레드를 이용하면 동시에 여러 일을 수행 가능하게 해줍니다.

 

- Light Weight Process라고도 합니다.

 

스레드의 특징 및 장점

# process와 달리 값은 process 내에서 자원을 메소드 / 함수 자원을 공유합니다.

# 멀티 스레드를 사용하면 멀티테스킹이 가능합니다.

# CPU의 유효시간을 최소화 시킬 수 있다.

# idle time을 최소화하면서 메소드 단위로 진행 할 경우 메모리 절약, 여러개 응용프로그램을 동시 조작 가능

 

스레드를 사용하기 위해선 다음과 같은 모듈을 호출합니다.

import threading

 

Ex 1) 스레드를 사용한 경우와 사용하지 않은 경우 차이점 알기

 

def run(id):
    for i in range(1,4):
        print('id : {} --> {}'.format(id, i))

# thread를 사용하지 않는 경우
# 순서대로 출력합니다. -> 일 3번찍고 둘 3번찍고
run('일')
run('둘')        
print()


# 출력 결과

id : 일 --> 1
id : 일 --> 2
id : 일 --> 3
id : 둘 --> 1
id : 둘 --> 2
id : 둘 --> 3

프로그램종료

우선, 스레드를 사용하지 않은 소스코드입니다.

 

for문이 1부터 3번을 반속 수행하는데 스레드를 사용 하지 않았기 때문에, 하나의 작업을 끝마친후 다음 작업을 진행하는 것을 알 수 있습니다.

 

이번에는 스레드를 사용한 경우

 

- 여기서 스레드를 사용할 경우 랜덤으로 실행되지만, 실행 순서를 정해줄 순 없다.

변수명 = threading.Thread(target=스레드 진행할 함수, args=(돌릴 인자))

변수명.start() : 스레드 시작시 사용

변수명.join() : 스레드가 종료되길 기다릴 경우

변수명.run() : 스레드의 동작을 정의

 

import threading

def run(id):
    for i in range(1,4):
        print('id : {} --> {}'.format(id, i))
        time.sleep(0.3) # 동시에 돌아가는것을 보여주기위해 작성

th1 = threading.Thread(target=run, args=('일'))
th2 = threading.Thread(target=run, args=('둘'))

th1.start()
th2.start()

th1.join()
th2.join()


# 출력 결과

id : 일 --> 1
id : 둘 --> 1
id : 일 --> 2
id : 둘 --> 2
id : 일 --> 3
id : 둘 --> 3
프로그램종료

 

th1 스레드 1번 th2 스레드 1번 이 과정을 반복하여 실행되는 결과를 볼 수 있습니다.

 

다음으로 join() 함수를 사용하지 않고, 출력한 경우의 출력 결과입니다.

# 출력 결과

id : 일 --> 1
id : 둘 --> 1
프로그램종료
id : 일 --> 2
id : 둘 --> 2
id : 둘 --> 3
id : 일 --> 3

 

차이점은 다음과 같습니다.

join 함수를 사용하지 않으면 스레드가 끝나길 기다리지 않고, print() 문의 '프로그램종료' 를 출력 후 다시 작동하는 것을 볼 수 있습니다.

반면 join() 함수를 사용한 경우 스레드 과정을 다 마친 후에 print() 문을 출력한 사실을 알 수 있습니다.

 

 

Ex 2) thread와 time 모듈을 이용하여 날짜 및 시간을 출력하기

import time

 

time 모듈의 localtime() 함수를 가지고 존재하는 속성값

tm_year

년도(4자리 작성)

tm_mon

월(1~12)

 

tm_mday

일(1~31)

tm_hour

시(0~23)

tm_min

분(0~59)

tm_sec

초(0~60)

tm_wday

각 요일을 숫자로 나타냅니다. (월요일= '0')

tm_yday

1월 1일부터 오늘까지 일 수 (1~365)

 

# 이 소스코드는 스레드를 사용하지 않았습니다.

now = time.localtime()

print('현재는{}년  {}월 {}일'.format(now.tm_year, now.tm_mon, now.tm_mday))
print('{}시 {}분  {}초'.format(now.tm_hour, now.tm_min, now.tm_sec))
print('오늘은  {} 요일 이고 올해  {} 번째 날'.format(now.tm_wday, now.tm_yday))


# 출력 결과

현재는2020년  5월 15일
17시 25분  53초
오늘은  4 요일 이고 올해  136 번째 날
프로그램  종료

 

thread를 사용하여 현재 진행중인 시간 1초마다 반복 출력

 

import time
import threading

def cal_show():
    now = time.localtime()
    print('현재 {} 년  {} 월 {} 일'.format(now.tm_year, now.tm_mon, now.tm_mday), end = ' ')
    print('{} 시  {} 분   {} 초'.format(now.tm_hour, now.tm_min, now.tm_sec))

def myRun():
    while True:
        now2 = time.localtime()
        if now2.tm_min == 34: break
        cal_show()
        time.sleep(1)
  
th = threading.Thread(target=myRun)
th.start()
th.join()

print('프로그램  종료')


# 출력 결과

현재 2020 년  5 월 15 일 17 시  28 분   6 초
현재 2020 년  5 월 15 일 17 시  28 분   7 초
현재 2020 년  5 월 15 일 17 시  28 분   8 초
현재 2020 년  5 월 15 일 17 시  28 분   9 초
현재 2020 년  5 월 15 일 17 시  28 분   10 초
현재 2020 년  5 월 15 일 17 시  28 분   11 초
현재 2020 년  5 월 15 일 17 시  28 분   12 초
현재 2020 년  5 월 15 일 17 시  28 분   13 초
현재 2020 년  5 월 15 일 17 시  28 분   14 초
현재 2020 년  5 월 15 일 17 시  28 분   15 초
현재 2020 년  5 월 15 일 17 시  28 분   16 초
현재 2020 년  5 월 15 일 17 시  28 분   17 초
현재 2020 년  5 월 15 일 17 시  28 분   18 초
현재 2020 년  5 월 15 일 17 시  28 분   19 초
현재 2020 년  5 월 15 일 17 시  28 분   20 초

 

 

반응형
반응형

* 윈도우에서 python용 MySql(MariaDB) 드라이버 설치 방법

버전별 드라이버 다운로드 http://www.lfd.uci.edu/~gohlke/pythonlibs/

사이트에서 mysqlclient 로 검색하여 원하는 파일( mysqlclient-1..-cp3*-cp3*m-win_amd64.whl )을 다운로드하면 된다.

확장자를 zip으로 변경하고 압축을 풀어준다. 

풀린 파일과 폴더들을 복사한 후 C:\Python3*\Lib\site-packages 에 붙여넣기 하면 된다.

또는 pip install ... 해주면 된다.

이클립스에서 MariaDB를 연결하는 방법은 다음과 같습니다.

 

방법 1.

conn = MySQLdb.connect(host = '127.0.0.1', user = '사용자이름', password='비밀번호', database='DB명')

ex)
conn = MySQLdb.connect(host = '127.0.0.1', user = 'root', password='123', database='test')

또는 다음과 같이 작성해주시면됩니다.

 

config = {

    'host':'127.0.0.1',
    'user':'사용자이름',
    'password':'비밀번호',
    'database':'DB명',
    'port':3306,
    'charset':'utf8',
    'use_unicode':True
}

ex)

config = {

    'host':'127.0.0.1',
    'user':'root',
    'password':'123',
    'database':'test',
    'port':3306,
    'charset':'utf8',
    'use_unicode':True

}

 

이번에는 제가 만든 테이블에 데이터를 삽입하고 결과를 출력해보겠습니다.

 

table prac

CREATE TABLE prac(num INT(255) NOT NULL PRIMARY KEY,
NAME VARCHAR(20),
HOUR INT(11),
pay INT(11))
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;

 

 

위 DB연결 코드 밑에 데이터 삽입 SQL문을 넣고 결과를 보겠습니다

 

try:
    conn = MySQLdb.connect(**config)
    print(conn) # DB가 잘 연결되었는지 확인
    cursor = conn.cursor() # SQL문 수행을 위한 커서 객체 생성
    
   
        
except Exception as e:
    print('err : ',  e) 
    
finally:
    cursor.close()
    conn.close()

# print(conn) 의 출력 결과
<_mysql.connection open to '127.0.0.1' at 0000025181F6F578>

try문 내의 코드는 다음과 같습니다.

 

- import MySQLdb 를 하여 MySQLdb 모듈을 불러옵니다.

 

- MySQLdb.connect(**config) 메소드를 통하여 MySQL에 연결해줍니다. 호스트명, 사용자명, 암호, 접속할 DB, 포트, 등을 기재합니다.

 

- DB 접속이 성공하면, Connection 객체로부터 cursor() 메서드를 호출하여 Cursor 객체를 가져옵니다.

 

- cursor 객체를 생성하였다면 이제 이 객체로 SQL의 DML 명령어들을 다 수행할 수 있습니다.

 

이제 자료를 추가하고 수정하고 삭제하는 DML 명령어들을 작성해보겠습니다. 

 

지금부터 작성되는 내용들은 try ~ except 안에 추가로 작성해주시면됩니다.

 

1. 자료 추가 ( insert ) , 자료 조회 ( select )

방법 1.

# 자료 추가
    sql = "insert into prac(num, NAME, HOUR, pay) values (1, '홍길동',3,8000)"
    cursor.execute(sql) # 결과가 1이면 commit한다 아니면 rollback execute에 사실 리턴값이 존재
    conn.commit()
    
#select 전체자료 읽기
    sql = 'select * from prac'
    cursor.execute(sql)
    
    # 출력1 튜플 타입으로 출력된다
    for data in cursor.fetchall():
        print(data)
        
        
# 출력결과

(1, '홍길동', 3, 8000)

 insert 문을 사용하여 각각의 컬럼에 맞게 값들을 입력해주었습니다.

 

이후 cursor객체에 execute를 사용해  실행할 sql문이 들어있는 변수를 입력해줍니다.

그 후 commit() 과정을 해주어야 합니다.

그 이유는 Autocommit 이 아니기때문입니다. 자동으로 commit 실행을 하고싶다면, connect() 메서드 호출시 autocommit=True 를 지정해줍니다.

 

insert문이 잘 실행되었는지 보기 위해 select 문도 작성하고, 반복문 for을 통해 데이터가 잘 삽입 되었는지 출력해보았습니다.

 

이번에는 다른 방법으로 insert 문과 select문을 사용해보겠습니다.

방법 2.

 sql = "insert into prac values(%s,%s,%s,%s)" # 자바는 values에 ?가 들어감
    sql_data = (2, 'insert2','5', 9000)
    cursor.execute(sql, sql_data)
    conn.commit()
    
    
    
     # 출력 2 
     # 반복문 for에 cursor 객체 값들을 r에 넣고 출력
     # list로 출력
    for r in cursor: 
    
     # 배열에 저장되는 값들은 다음과 같습니다.
        print([r[0], r[1], r[2], r[3]]) # r[0] = num값 r[1] name값 r[2] HOUr값 r[3] pay값 저장     
        
# 출력 결과

[1, '홍길동', 3, 8000]
[2, 'insert2', 5, 9000]


 

방법 3.

 

    sql = "insert into prac values(%s,%s,%s,%s)" # 자바는 values에 ?가 들어감
    sql_data = '3','insert3',5,6000
    cursor.execute(sql, sql_data)
    conn.commit()

# 출력 3
# 이번에는 매핑을 이용하여 서로 값이 일치하게 저장되도록 합니다.
    for (num, NAME, HOUR, pay) in cursor:
        print(num, NAME, HOUR, pay)
       	print()

# 출력4
    for (a, b, c, d) in cursor: # 매핑한거라 값은 같게 출력
        print(a, b, c, d)

# 출력 결과

1 홍길동 3 8000
2 insert2 5 9000
3 insert3 5 6000

1 홍길동 3 8000
2 insert2 5 9000
3 insert3 5 6000

 

update / delete 문 사용 후 출력 방식은 출력 1에서 사용한 방법으로 출력하도록 하겠습니다.

 

2. UPDATE

# 자료 수정

    sql = "update prac set NAME = %s, HOUR=%s, pay=%s where num=%s"
    sql_data = ('홍씨에서이씨', 5, 10000, 1)
    cursor.execute(sql, sql_data)
    conn.commit()


    #select 전체자료 읽기
    sql = 'select * from prac'
    cursor.execute(sql)
    
    # 출력1

    for data in cursor.fetchall():
        print(data)
        
        
# 출력 결과

(1, '홍씨에서이씨', 5, 10000)
(2, 'insert2', 5, 9000)
(3, 'insert3', 5, 6000)

 

3. DELETE

 

방법 1)

 

    # 자료 삭제 
    num = '1'
    sql = "delete from prac where num = " + num #권장x
    cursor.execute(sql)
    conn.commit()


	# 출력 결과
    
    (2, 'insert2', 5, 9000)
	(3, 'insert3', 5, 6000)

 

방법 2)

 

    num = '2'

    sql = "delete from prac where num='{0}'".format(num) 
    cursor.execute(sql)
    conn.commit()
    
    
    # 출력 결과
    
    (3, 'insert3', 5, 6000)

 

방법 3)

 

    num = '3'

    sql = "delete from prac where num=%s" #가장많이 쓰는 방법 밑에 cursor와 매핑 할땐 튜플형태로 줘라
    cursor.execute(sql, (num, ))
    conn.commit()
    
    
    # 출력 결과
    
    

 

참고사이트

 

https://cafe.daum.net/flowlife

 

반응형

'python' 카테고리의 다른 글

[python] Numpy 데이터타입, 메모리저장, 배열  (0) 2020.05.28
python - Thread ( 스레드 ) (1)  (0) 2020.05.14
python - 예외처리  (0) 2020.05.11
python - OS & pickle  (0) 2020.05.11
python - 상속 (2)  (0) 2020.05.10
반응형

예외처리란 ?

문법 또는 여러가지 이유로 오류가 발생하지만 오류를 무시하고 싶을 때 파이썬은 try, except를 사용해서 예외적으로 오류를 처리할 수 있게 해주는 것이 예외처리 입니다.

 

예외처리 형식은 다음과 같습니다.

try:
    실행할 소스코드
except [발생 오류[as 오류 메시지 변수]]:
    오류 일경우 출력 하고 싶다면 작성

예제 ZeroDivisionError - 0으로 나눌경우 예외처리

# 예외처리 try ~ except

def divide(a,b):
    return a / b


try:
    #c = divide(5,2)
    c = divide(5,0)

except ZeroDivisionError:
    print('두번째 숫자는 0을 빼고 주세요')


print('종료')


출력 결과

작업 후
두번째 숫자는 0을 주지 마시오
종료

 

소스코드에서 다음과 같은 함수를 주었습니다. 

a / b 의 계산을 하는데 0으로 나눌경우 ZeroDivisionError라는 예외처리를 하였습니다.

c = divide(5,0)을 작성할 경우 5 나누기 0을 의미하는 거이기 떄문에 위의 에러로 인한 예외처리가 발생하였습니다.

 

0이 아닌 divide(5,2)를 주면 출력 결과는 당연히 예외처리 부분을 제외한 나머지가 출력될 것입니다.

 

예외처리 IndexError - 참조 범위 오류

# 예외처리 try ~ except

def divide(a,b):
    return a / b

try:

    aa = [1,2]
    print(aa[0])

except IndexError as e:
    print('참조 범위 오류 : ', e)
    
except Exception as err:
    print('기타에러' + str(err)) 

print('종료')

 

이번에는 참조 범위를 벗어나면 예외처리를 해보겠습니다. 배열 aa는 1과 2를 저장하였고,

print 출력에서 0번째를 출력하도록 하였습니다. 

 

현재는 출력하면 1이 출력될 것입니다.

 

하지만 다음과 같이 바꿔주면

print(aa[3])

aa배열의 3번째는 없기때문에

다음과 같은 예외처리가 발생합니다.

 

finally

 

finally문은 try 수행 도중 예외 발생 여부에 상관없이 수행되는 문장입니다.

보통 close해야 할 때에 많이 사용합니다.

 

형태는 다음과 같습니다.

try:
	소스코드
    
except Exception as e:
    print('err : ' + e) 
    
finally:
    cursor.close()
    conn.close()
반응형

'python' 카테고리의 다른 글

python - Thread ( 스레드 ) (1)  (0) 2020.05.14
python - DataBase 연동 & SQL 작업  (0) 2020.05.13
python - OS & pickle  (0) 2020.05.11
python - 상속 (2)  (0) 2020.05.10
python - 상속  (0) 2020.05.10
반응형

외장함수중 하나인 OS 모듈이란 ?

- 환경 변수나 디렉터리, 파일 등의 OS 자원을 제어한다.

 

디렉터리의 위치를 돌려받고 싶은 경우 - os.getcwd()

import os

print(os.getcwd())



출력 결과
자신이 사용하고 있는 파이썬 저장 경로가 출력됩니다

 

파일 읽기 

 

파일을 불러올 txt 파일

 

ftest.txt

푸른하늘
은하수
하얀 쪽배에

 

 

import os

print(os.getcwd())

try:
    print(os.getcwd())

    print('파일 읽기')
    f1 = open(r'ftest.txt', mode='r', encoding='utf-8') # open 장치 열고
    print(f1.read())
    f1.close()
    
    
    
except Exception as e:
    print(e)
        
    
    
출력 결과

파일 읽기
푸른하늘
은하수
하얀 쪽배에

 

파일 저장

 

import os

print(os.getcwd())

try:
    print(os.getcwd())
    
    print('파일 저장 ')
    f2 = open('ftest2.txt', mode='w', encoding='utf-8')
    f2.write('kbs\n')
    f2.write('월요일 아침\n')
    f2.write('mbc11')
    f2.close()
    print('저장성공')
    
    
except Exception as e:
    print(e)
        
    
    
출력 결과

파일 저장 
저장성공

 

다음과 같이 출력이 되면서 해당 경로에

 

ftest2.txt 파일이 생성됩니다.

 

 

파일 추가

import os

print(os.getcwd())

try:
    print(os.getcwd())
print('파일 추가')
    f3 = open('ftest2.txt', mode='a', encoding='utf-8')
    f3.write('sbs\n')
    f3.write('홍길동\n')
    f3.close()
    print(' 추가 성공')
    
    
except Exception as e:
    print(e)
        
        
출력 결과

파일 추가
 추가 성공

 

위와 같은 출력 결과가 나타나면서 파일이 추가 된 것을 알 수 있습니다.

 

 

 

여러 종류의 객체 저장 및 읽는 방법은 pickle 외장 함수를 사용한다.

 

pickle 이란 ?

 

- 객체의 형태를 그대로 유지하고, 파일에 저장하고 읽기가 가능한 모듈이다.

 

import pickle
        
try:        
    dicdata = {'tom':'111-1111', '길동':'222-2222'}
    listdata = ['마우스','키보드']
    tupledata = (dicdata, listdata) # 복합 개체
    
    with open('hi.dat', 'wb') as ff3:
        pickle.dump(tupledata, ff3)
        pickle.dump(listdata, ff3)
        
    print('읽기')
    with open('hi.dat', 'rb') as ff4:
        a,b = pickle.load(ff4)
        print(a)
        print(b)
    
except Exception as err:
    print('에러 : ',err)
    
   
   
출력 결과

{'tom': '111-1111', '길동': '222-2222'}
['마우스', '키보드']

소스코드에서 딕셔너리 자료와 리스트 자료를 만들고 튜플 자료에 두개의 개체를 넣어서 복합 개체로 정의해주었습니다.

그리고 그 파일자료를 읽으면 어떤 자료형이든저장하고 불러올 수 있고, 위와 같은 결과가 나타납니다.납니다.

 

 

 

반응형

'python' 카테고리의 다른 글

python - DataBase 연동 & SQL 작업  (0) 2020.05.13
python - 예외처리  (0) 2020.05.11
python - 상속 (2)  (0) 2020.05.10
python - 상속  (0) 2020.05.10
python - 클래스  (0) 2020.05.10
반응형

2020/05/10 - [python] - python - 상속

 

python - 상속

클래스에서 상속이란 ? - 부모 클래스의 내용을 받는 자식클래스가 받아서 사용하게 되는 것입니다. - 형태는 다음과 같습니다. class 부모클래스: 소스코드 class 자식클래스(부모클래스): 소스코��

lightchan.tistory.com

 

이전 포스팅 글에 의어서

 

상속 예제를 들어보겠습니다.

 

class Person:
    say = '안녕하세요 제 나이는 '
    nai = 20
    
    def __init__(self, nai):
        print('Persion 생성자')
        self.nai = nai
        
    def PrintInfo(self):
        print('이야기 :{} {}'.format(self.say, self.nai))
        
p = Person('22')
p.PrintInfo()


출력 결과

Persion 생성자
이야기 :안녕하세요 제 나이는  22

 

우선 Person 이라는 클래스를 생성하고, 생성자에 nai라는 변수를 주었습니다.

이후 p 객체를 생성하기 위에선 nai가 필요하기 때문에 나이를 22로 주었고 그에 따른 해당 출력 결과는

위와 같이 출력됩니다.

 

그럼 이제 자식 클래스를 만들어서 상속받아겠습니다.

 

class Student(Person):
    say = '공부하는 '
    subject = '학생'
    
    def __init__(self):
        print('Student 생성자생성')
        
    def PrintInfo(self):
        print('Student의 PrintInfo')    
                
    def EprintInfo(self):
        print(self.say, ' ' , super().say)
        super().PrintInfo() # super() 붙어서 처음부터 부모꺼
        self.PrintInfo() # 자기꺼 있으면 자기꺼 없으면 부모꺼
        
e = Student()
print(e.say, ' ' , e.nai, '살 ' , e.subject)
        
e.EprintInfo()  


출력 결과

Student 생성자생성
공부하는    20 살  학생
공부하는    안녕하세요 제 나이는 
이야기 :공부하는  20
Student의 PrintInfo

소스코드를 보시면

Student 클래스는 Person 부모클래스로부터 상속 받고있습니다.

 

그리고 Student 생성자를 생성하는 함수가 작성되어있습니다. 여기서 생성자가 작성되어있지 않다면 부모 클래스의 생성자를 따라가게 되어있습니다. 그렇다면 부모클래스의 생성자는 nai를 받기 떄문에 

 

Student 클래스에서 e 라는 변수로 객체를 생성할때 e = Student(나이값) 과 같이 나이 값을 넣어주어야 오류가 발생하지 않습니다.

 

 

EprintInfo() 함수에서 부모클래스의 say를 받아서 출력하는 것을 알 수 있습니다.

 

super() 여기서 super()는 부모클래스의 내용을 자식클래스에서 사용하고 싶은 경우 쓸 수 있습니다.

 

 

이번에는 다중 상속에 대해 알아보겠습니다.

 

다중 상속이란?

2개 이상의 클래스를 받아 사용하는 것을 뜻합니다.

 

우선 부모 클래스로 사용할 클래스 2개를 만들어보겠습니다.

 

class A:
    data = '파이썬'
    
    def Std(self):
        print('파이썬 공부')
        
    def Std1(self):
        print('파이썬 공부는 재밌다.')
        
        
class B:
    def Std(self):
        print('자바 공부')
        
    def dif(self):
        print('자바 공부는 어렵다')
        
    def kbs(self): 
        pass # 필수는 아니지만 다형성을 위해 강요 가능함

부모클래스 A와 B를 생성하였습니다.

 

이제 이 부모클래스를 호출할 자식 클래스를 만들어서 호출해보겠습니다.

 

class C(A, B):
    pass        

aa = C()

# 중복일 경우 먼저 상속한 값으로 가져옴 그래서 A.Std() 가져옴
aa.Std()
aa.Std1()
aa.dif()
print(aa.data)


출력 결과

파이썬 공부
파이썬 공부는 재밌다.
자바 공부는 어렵다
파이썬

자식클래스 C를 생성하였습니다.

부모 클래스 A에서 Std 함수가 존재하고 부모 클래스 B에도 Std 함수가 존재한다.

하지만 출력 결과를 보면 주석에도 언급하였듯, 먼저 상속받은 클래스의 함수를 출력 시키는 것을 알 수 있습니다.

 

이번에는 자식클래스 D를 만들어 C클래스와 반대로 해보겠습니다.

class D(B, A):
    data = '프로그래밍 천국'
    
    def Play(self):
        self.Std()
        super().Std()
        
    def dif(self):
        print('어려워도 열심히하려한다.')
        
bb = D()
# 중복일 경우 먼저 상속한 값으로 가져옴 그래서 B.Std() 가져옴
bb.Play()
bb.dif()


출력 결과

자바 공부
자바 공부
어려워도 열심히하려한다.

 

 

 먼저 호출한 부모클래스의 함수를 가져오는 것을 알 수 있습니다.

 

 

추상 클래스

추상 클래스란?

추상 클래스는 기본골격을 만들고 상속받는 클래스에서 그 구현을 강제로 시키는 클래스입니다.

형식을 다음과 같습니다.

 

from abc import *
class 추상클래스이름(metaclass=ABCMeta):

     @abstractmethod
        def 추상메소드(self):
            pass

 

바로 예제로 들어가도록 하겠습니다.

 

추상클래스 AbstractCalss

from abc import *

class AbstractClass(metaclass=ABCMeta):
    # ABCMeta 클래스의 서브 클래스는 추상 클래스
    
    @abstractclassmethod
    def abcMethod(self): # 추상 메소드
        pass
    
    
    def normalMethod(self):
        print('AbstractClass 클래스의 일반 메소드')
        

 

이 추상 클래스를 받아서 사용할 Child1 클래스

class Child1(AbstractClass):
    name = 'Child1입니다.'

    def abcMethod(self):
        print('추상메소드를 오버라이딩')

c1 = Child1()

print(c1.name)

c1.abcMethod()
c1.normalMethod()


출력 결과

Child1입니다.
추상메소드를 오버라이딩
AbstractClass 클래스의 일반 메소드

 

AbstractClass 추상클래스에서 abcMethod를 추상메소드로 주었고,

 

Child1 클래스에서 위 추상클래스를 받아서 사용 하도록 하였습니다.

 

위와 같이 작성하면 추상클래스의 미구현 메소드를 받아 사용하였기 때문에 아무런 문제가 없이 잘 출력됩니다.

 

이번에는 추상클래스를 좀 더 자세히 보기 위해 Child1 클래스에서 받았던 미구현 추상메소드를 지워보겠습니다.

 

class Child1(AbstractClass):
    name = 'Child1입니다.'

c1 = Child1()

print(c1.name)

c1.abcMethod()
c1.normalMethod()

 그럼 다음과 같은 오류 메세지를 출력합니다.

 

이러한 에러를 출력하는 이유는 임포트 과정에서 에러를 출력하진 않지만 추상클래스에서 미구현 메소드를 Child1 클래스에서 받지 않고 객체 생성을 하려했기 때문에 객체 생성 과정에서 오류가 발생하는 것입니다.

 

 

2020/05/10 - [python] - python - 상속

 

python - 상속

클래스에서 상속이란 ? - 부모 클래스의 내용을 받는 자식클래스가 받아서 사용하게 되는 것입니다. - 형태는 다음과 같습니다. class 부모클래스: 소스코드 class 자식클래스(부모클래스): 소스코��

lightchan.tistory.com

 

반응형

'python' 카테고리의 다른 글

python - 예외처리  (0) 2020.05.11
python - OS & pickle  (0) 2020.05.11
python - 상속  (0) 2020.05.10
python - 클래스  (0) 2020.05.10
python - 재귀함수  (0) 2020.05.10
반응형

클래스에서 상속이란 ?

 

- 부모 클래스의 내용을 받는 자식클래스가 받아서 사용하게 되는 것입니다.

- 형태는 다음과 같습니다.

 

class 부모클래스:
	소스코드
    
class 자식클래스(부모클래스):
	소스코드

 

class Animal: # 부모클래스
    def __init__(self):
        print('animal 생성자')
        
    def move(self):
        print('움직이는 동물')
        
class Dog(Animal):  # 자식클래스
    def __init__(self): # 해당 클래스의 생성자가 없으면 부모 생성자를 부르고 생성자가 있으면 자신을 호출한다.
        print('Dog 생성자')
    
    def my(self):
        print('나는 개')

dog1 = Dog()

dog1.my()
dog1.move()


출력 결과

Dog 생성자
나는 개
움직이는 동물

 

부모클래스 Aninal의 '움직이는 동물'을 자식클래스 Dog가 가져다가 사용하여 위와 같은 출력 결과를 가지고 온 것을 알 수 있습니다.

 

여기서 부모클래스의 생성자를 가지고 오지 않는 이유는 주석에도 알 수 있듯이, 자식클래스에서 생성자가 있기 때문입니다.

 

 

오버라이딩 

 

-  부모 클래스의 메소드를 자식 클래스에서 재정의 하는 것입니다.

 

다형성

 

- 부모 클래스로부터 물려받은 내용을 자식 클래스 내에서 오버라이딩하여 사용하는 것입니다.

 

class Parent: # overriding
    def Prindata(self):
        pass
    
class Child1(Parent):
    def Prindata(self):
        print('Child1에서 overrding')
            
            
class Child2(Parent):
    def Prindata(self):
        print('Child2에서 재정의')
        
    def abc(self):
        print('Child2 고유 메소드')
        
c1 = Child1()
c1.Prindata()

c2 = Child2()
c2.Prindata()   


출력 결과


Child1에서 overrding
Child2에서 재정의

 

부모클래스인 Child1 에서 Printdata 메소드는 'child1에서 overrding'을 출력해준다.

하지만 오버라이딩 성질을 이용하면 Child2에서 Printdata 메소드의 출력문인 'Child2에서 재정의' 를 출력해줍니다.

 

 

2020/05/10 - [python] - python - 상속 (2)

 

python - 상속 (2)

이전 포스팅 글에 의어서 상속 예제를 들어보겠습니다. class Person: say = '안녕하세요 제 나이는 ' nai = 20 def __init__(self, nai): print('Persion 생성자') self.nai = nai def PrintInfo(self): print('..

lightchan.tistory.com

 

반응형

'python' 카테고리의 다른 글

python - OS & pickle  (0) 2020.05.11
python - 상속 (2)  (0) 2020.05.10
python - 클래스  (0) 2020.05.10
python - 재귀함수  (0) 2020.05.10
python - 함수 장식자 ( Decorator )  (0) 2020.05.10
반응형

클래스란 ?

 

- 객체의 구조를 나타낸다.

- 클래스에 의해 만들어진 객체를 인스턴스라고도 부른다.

 

 

객체와 인스턴스의 차이

- 객체는 클래스 정의시 메소드 밖에 존재하며, 클래스명.변수명 으로 사용한다. 

- 인스턴스는 메소드 안에서 사용하며, self.변수명으로 사용한다.

 

# 모듈의 멤버로 클래스

class TestClass:
    kk = 1 # 멤버변수 ( 전역 )
    
    def __init__(self):
        print('생성자')
        
    def __del__(self):
        print('소멸자')
        
    def printMsg(self): # 메소드 (public)
        name = '한국인' # 지역변수
        print(name)
        print(self.kk)
        
test = TestClass() # 생성자 호출. instance
print(test.kk) # 1을 출력
print(TestClass.kk) # prototype(원형) 클래스의 멤버 직접 호출
 
print()

test.printMsg() # Bound Method call
# TestClass.printMsg() # 이렇게 주면 아규먼트를 주지 않아서 ERR
print()
TestClass.printMsg(test) # UnBound Method call


출력 결과

생성자
1
1

한국인
1

한국인
1

소멸자

 

# Bound Method Call는 self가 붙은 쪽에 사용하고, UnBound Method Call 이란 self 를 안 붙은 쪽을 말합니다.

 

파이썬에서 사용하는 특별한 메소드

 

# __init__ : 

- 초기화(initialize) 메서드라고도 합니다.

- 어떤 클래스의 객체가 만들어질 때 자동으로 호출되어서 그 객체가 갖게 될 여러 가지 성질을 정해주는 역할을 함

- 위 소스에서는 TestClass() 를 작성하여 TestClass 객체를 생성하자마자 초기화가 되고 '생성자'를 출력하였습니다.

 

# __del__ :

- 객체가 없어질때 사용하는 메소드입니다.

- 위 소스에서는 그래서 맨 마지막에 '소멸자'가 출력되었습니다.

 

 

 

이번에는 __init__ 메소드에 인자를 받아야만 생성자가 생성되는 예제를 들어보겠습니다.

 

class Car:
    handle = 0
    speed = 0

    def __init__(self, name, speed):
        self.speed = speed
        self.name = name
        
    def showData(self):
        km = '킬로미터'
        msg = '속도:' + str(self.speed) + km
        return msg
    
print(Car.handle)
print(Car.speed)
#print(Car.name) # type object 'Car' has no attribute 'name'
print()
car1 = Car('tom',10)
print(car1.handle, car1.name, car1.speed)
print('------')
car2 = Car('james',20)
print(car2.handle, car2.name, car2.speed)

print()
print(car1.showData())
print(car2.showData())
car1.speed = 88
car2.speed = 100
print(car1.showData())
print(car2.showData())

Car.handle = 1
print(car1.handle)
print(car2.handle)


출력 결과

0
0

0 tom 10
------
0 james 20

속도:10킬로미터
속도:20킬로미터
속도:88킬로미터
속도:100킬로미터
1
1

 

위 소스코드는 __init__ 생성자에 self, name, speed 를 주었기 때문에 새로운 객체를 생성할때 name,과 speed를 가지고 가야 생성이 가능합니다. 그렇지 않으면 다음과 같은 에러를 출력합니다.

 

 

car1 객체와 car2 객체를 생성 한 후에는 speed 값을 기존 10에서 각각 88과 100으로 변경해주었습니다.

그 출력 결과 속도들의 변경된 점을 확인 가능했습니다.

 

# 클래스는 포함자원의 재활용 목적으로 다른 클래스를 불러다가 사용 가능합니다.

 

handle.py

 

# 다른 클래스에서 공유할 클래스

class PohamHandle:
    quantity = 0
    
    def LeftTurn(self, quantity): # self에 quantity 가 들어옴
        self.quantity = quantity
        
        return '좌로 돌아';
    
    def RightTurn(self, quantity): # self에 quantity 가 들어옴
        self.quantity = quantity
        
        return '우로 돌아';

 

PohanCar.py

 

import etc.handle

class PohanCar:
    turnShow = '정지'
    
    def __init__(self, ownerName):
        self.ownerName = ownerName
        self.handle = etc.handle.PohamHandle()
        
        
    def TurnHandle(self, q):
        if q > 0:
            self.turnShow = self.handle.RightTurn(q)
        elif q < 0:
            self.turnShow = self.handle.LeftTurn(q)
        else:
            self.turnShow = '직진'
            
if __name__ == '__main__':
    tom = PohanCar('tom')
    tom.TurnHandle(10)
    print(tom.ownerName + ' 의 회전량은 ' + tom.turnShow + str(tom.handle.quantity))            
    
    print()
    james = PohanCar('james')
    james.TurnHandle(0)
    print(james.ownerName + ' 의 회전량은 ' + james.turnShow + str(james.handle.quantity))

 

출력 결과

 

반응형

'python' 카테고리의 다른 글

python - 상속 (2)  (0) 2020.05.10
python - 상속  (0) 2020.05.10
python - 재귀함수  (0) 2020.05.10
python - 함수 장식자 ( Decorator )  (0) 2020.05.10
python - 파이썬은 1급 함수인가 ?  (0) 2020.05.08
반응형

재귀함수란 ?

 

- 함수 안에서 자신을 다시 호출하는 방법입니다.

- 함수 내에서 자신을 다시 호출한 후 함수가 끝나는 이후에는 종료 조건을 붙여주어야 무한루프에 빠지지 않습니다.

 

 

def CountDown(n):
    if n == 0:
        print('완료')
        
    else:
        print(n, end=' ')
        CountDown(n - 1)
 
CountDown(5)


출력 결과

5 4 3 2 1 완료

 

CountDown 함수에 5가 들어간후 if문을 실행합니다. n == 5이기 때문에 else 문을 실행하고,

그 다음 n - 1 을 통해 n는 4가 되고 다시 if문을 거쳐 else 문을 실행하게 됩니다.

이 과정을 반복하다가 n이 0이 될 경우 완료를 출력하고 빠져나오게 됩니다.

 

예제 2)

def fact(a):
    if a== 1: return 1
    print(a)
    return a * fact(a-1)

result2 = fact(5)
print('5! : ' + str(result2))


출력 결과
5! : 120

 

예제 3)

def tot(n):
    if n == 1:
        print('탈출')
        return 1
    return n + tot(n-1)
result = tot(10)
print('합은' + str(result))


출력 결과

탈출
합은 55

 

위 예제는 if문을 주었지만 이번 예제는 루프 과정을 반복하다가 n이 1을 만나면 탈출하는 예제입니다.

 

이번 예제는 위와 동일한 원리입니다.

반응형

'python' 카테고리의 다른 글

python - 상속  (0) 2020.05.10
python - 클래스  (0) 2020.05.10
python - 함수 장식자 ( Decorator )  (0) 2020.05.10
python - 파이썬은 1급 함수인가 ?  (0) 2020.05.08
python - 가변인수  (0) 2020.05.08

+ Recent posts