본문 바로가기
코딩 연습/코딩배우기

[Python] 파이썬 기본기 UP - 함수, 클래스, DB 다루기

by good4me 2021. 7. 20.

goodthings4me.tistory.com

 

파이썬 기본기 UP - 파이썬의 기본 문법을 정리하기 좋은 강의 영상이 있어서 정리함. 함수의 호출(인자, 매개변수), 클래스에서 접근제한 하는 법, 상속과 다형성(오버라이딩), 그리고 DB 다루기(sqlite3, mariadb) 등을 중심으로 요약해보았다. 

 

■ 함수의 호출 인자(Argument), 매개변수(Parameter)

val1, *vals = (1, 2, 3, 4, 5)  # 언패킹
print(*vals)  # 2 3 4 5


def callFunc(*args):
    print(type(args))  # <class 'tuple'>
    result = 0
    for i in args:
        result += i
    return result

res = callFunc(10, 20, 30)
print(res)  # 60


def callFunc2(**kwargs):
    print(type(kwargs))  # <class 'dict'>
    tot = 0

    for k in kwargs.keys():
        tot += kwargs[k]
        print(f'{k} = {kwargs[k]}')
    return (tot, tot/len(kwargs))

    # for k, v in kwargs.items():
    #     tot += v
    #     print(f'{k} = {v}')
    # return (tot, tot/len(kwargs))

tot, avg = callFunc2(apple=10, banana=15, blueberry=20)  # (key=value | key='value')
print(f'합계 = {tot}, 평균 = {avg:.2f}')  # 합계 = 45, 평균 = 15.00


grade = {
    'apple': 11,
    'banana': 16,
    'blueberry': 21
}

tot, avg = callFunc2(**grade)
print(f'합계 = {tot}, 평균 = {avg:.2f}')  # 합계 = 48, 평균 = 16.00

##----------------------------------------------------------

def func1(a, lst=[]):
    lst.append(a)
    return lst

f1 = func1(10)
print(f1)  # [10]
f2 = func1(20)
print(f2)  # [10, 20]
print(id(f1), id(f2))  # 2770243496640 2770243496640
print(f1 is f2)  # True,  lst 공유

f3 = func1(30, [2,])
print(f3)  # [2, 30]


## 리스트 요소를 dict의 키로 만들어보기 dict().fromkeys()
lst = [2, 5, 1, 7, 2]
res_d = dict().fromkeys(lst)
print(res_d)  # {2: None, 5: None, 1: None, 7: None} 단, 중복은 제거됨
print(res_d.keys())  # dict_keys([2, 5, 1, 7])

##----------------------------------------------------------

import random
lo = range(1, 46)
sel_choice = random.choice(lo)  # 1개 추출
print(sel_choice)
sel_sample = random.sample(lo, 6)  # 6개 추출
print(sel_sample)

##----------------------------------------------------------

## 메서드
class MethodTest:
    def bound(self):
        print('bound!')
    
    def unbound():
        print('Unbound!')

m1 = MethodTest()
m1.bound()  # bound!
print(m1.bound)  
# <bound method MethodTest.bound of <__main__.MethodTest object at 0x0000020F4B08EBB0>>

# m1.unbound()  # TypeError: unbound() takes 0 positional arguments but 1 was given
# @staticmethod 붙이면 m1 객체에서 접근 가능

MethodTest.unbound()  # Unbound!
print(MethodTest.unbound)  # <function MethodTest.unbound at 0x000001F6B5A559D0>

 

■ 파이썬 클래스(class) 연습

class Person1:
    age = 30  # 클래스 변수
    def __init__(self, name, age):
        self.name = name
        self.age = age
        Person1.age += 1
    
    def disp(self):
        print(f'self.name : {self.name}')
        print((f'self.age : {self.age}'))
        print(f'Person.age : {Person1.age}')

p11 = Person1('임팔라', 12)
p11.disp()
# self.name : 임팔라
# self.age : 12
# Person.age : 31

p12 = Person1('임연수', 2)
p12.disp()
# self.name : 임연수
# self.age : 2
# Person.age : 32


class InsertPerson:
    def __init__(self):
        self.name = input('이름: ')
        self.age = input('나이: ')
    
    def disp(self):
        print(f'{self.name} : {self.age}')

person_list = []
for i in range(2):
    person_list.append(InsertPerson())

print(person_list)
# [<__main__.InsertPerson object at 0x000001BA2F3B26D0>, 
# <__main__.InsertPerson object at 0x000001BA2F3B2670>]

for p in person_list:
    p.disp()
# 홍길동 : 23
# 이순신 : 35


## 클래스 변수, 인스턴스 변수

class Person2:
    _p = 0  # 클래스 변수
    def __init__(self):
        Person2._p += 1
    
    def disp(self):
        print(f'self._p : {self._p}')  # 클래스 내에서 접근
        print(f'Person2._p : {Person2._p}')  # 클래스명으로 접근

p2 = Person2()
p2.disp()
print(f'p2._p : {p2._p}')  # 인스턴스로 직접 접근
# self._p : 1
# Person2._p : 1
# p2._p : 1


class Person21:
    _p = 0  # 클래스 변수
    def __init__(self):
        self._p = 20  # 인스턴스 변수
        Person21._p += 1
    
    def disp(self):
        print(f'self._p : {self._p}')  # 인스턴스 변수
        print(f'Person21._p : {Person21._p}')  # 클래스명으로 접근

p21 = Person21()
p21.disp()
print(f'p21._p : {p21._p}')  # 인스턴스 변수
# self._p : 20
# Person2._p : 1
# p2._p : 20


## 접근 제한자 '__변수' : 외부에 공개(X), 외부에서 접근(X)
class Person3:
    __gv = 0
    def __init__(self):
        self.__lv = 30
        Person3.__gv += 1
    
    def disp(self):
        print(f'self.__gv : {self.__gv}')
        print(f'self.__lv : {self.__lv}')

p3 = Person3()
p3.disp()
# self.__gv : 1
# self.__lv : 30

# print(p3.__gv)  # AttributeError: 'Person3' object has no attribute '__gv'
# print(p3.__lv)  # AttributeError: 'Person3' object has no attribute '__lv'
# print(Person3.__p)  # AttributeError: type object 'Person3' has no attribute '__p'


class Drink:
    __lst = []  # 클래스 변수
    def __init__(self, d):
        Drink.__lst.append(d)
    
    def disp(self):
        return self.__lst  # Drink.__lst

d1 = Drink('콜라')
print(d1.disp())  # ['콜라']
d2 = Drink('사이다')
print(d2.disp())  # ['콜라', '사이다']
# print(d2.__lst)  # AttributeError: 'Drink' object has no attribute '__lst'
# print(Drink.__lst)  # AttributeError: type object 'Drink' has no attribute '__lst'


class Drink2:
    def __init__(self, d):
        self.__lst = []  # 인스턴스 변수
        self.__lst.append(d)
    
    def disp(self):
        return self.__lst

d21 = Drink2('콜라')
print(d21.disp())  # ['콜라']
d22 = Drink2('사이다')
print(d22.disp())  # ['사이다']


## 객체를 parameter로 받아 처리하는 방법
class Animal:
    def __init__(self, name, age, obj) -> None:
        self.__name = name
        self.__age = age
        self.__obj = obj
    
    def disp(self):
        print(f'{self.__name} / {self.__age}세')
        self.__obj.sound()
    
class Tiger:
    def __init__(self, name) -> None:
        self._name = name
    def sound(self):
        print('어흥')

tiger = Tiger('호돌이')
animal2 = Animal(tiger._name, 3, tiger)
animal2.disp()

animal1 = Animal(Tiger('호순이')._name, 2, Tiger('호순이'))
animal1.disp()

good4me.co.kr


■ 상속(inheritance) & 다형성

class Parent:
    s = 'parent'
    def __init__(self):
        self.x = 5
        self.y = 10


class Son(Parent):  # Parent 상속, Parent 그대로 사용
    pass

s = Son()
print(s.s)  # parent
print(s.x)  # 5


class Son1(Parent):
    s = 'son'
    def __init__(self):  # Son1 __init__ 재정의(오버라이딩)
        self.x = 50
        self.y = 100

s1 = Son1()
print(s1.s)  # son
print(s1.x)  # 50


class Son2(Parent):
    s = 'son'
    def __init__(self):  # Son2 __init__ 재정의(오버라이딩)
        pass

s2 = Son2()
print(s2.s)  # son
# print(s2.x)  # AttributeError: 'Son2' object has no attribute 'x'


class Son3(Parent):
    s = 'son'
    def __init__(self, z):  # Son3 __init__ 재정의(오버라이딩)
        super().__init__()  # Parent의 __init__() 사용 시,  파이썬은 반드시 명시함
        self.z = z

s3 = Son3(100)
print(s3.s)  # son
print(s3.x)  # 5  Parent의 x
print(s3.z)  # 100


## 다형성 - 오버라이딩 (재정의)

class Point:
    def __init__(self):
        self.x = 800
        self.y = 600

    def disp(self):
        pass

class Circle(Point):
    def __init__(self):
        super().__init__()
        self.r = 50
    
    def disp(self):
        print('원', self.x, self.y, self.r)
    
class Rect(Point):
    def __init__(self):
        super().__init__()
        self.w = 400
        self.h = 200
    
    def disp(self):
        print('사각형', self.x, self.y, self.w, self.h)

circle = Circle()
circle.disp()  #  원 800 600 50

rect = Rect()
rect.disp()  # 사각형 800 600 400 200

 

■ json 만들기, json 파일 저장하고 읽어오기

import json

## json 만들기
info = {'name': '이코드', 'age': 27, 'job': 'programmer'}  # 사전형
print(info)  # {'name': '이코드', 'age': 27, 'job': 'programmer'}
print(type(info))  # <class 'dict'>

json_data = json.dumps(info)
print(json_data)  # {"name": "\uc774\ucf54\ub4dc", "age": 27, "job": "programmer"}
print(type(json_data))  # <class 'str'>


## json 파일로 저장
with open('./bokssam/info.json', 'w') as f:
    json.dump(info, f, ensure_ascii=False)  # ensure_ascii=False : 한글 저장

with open('./bokssam/info.json', 'r') as f:
    info_r = json.load(f)
print(type(info_r))  # <class 'dict'> 
print(info_r)  # {'name': '이코드', 'age': 27, 'job': 'programmer'}

 

■ sqlite3 db 다루기

## dbconn.py
import sqlite3

def getConn():
    conn = sqlite3.connect(r'C:\Users\hhhhh\OneDrive\myDev\bokssam\testdb.db')
    return conn
    
##------------------------------------------------------------------------

## sqlite3로 python db 다루기
import sqlite3

## table 생성
def create_table():
    # DB 접속 Connetion
    conn = sqlite3.connect(r'C:\Users\hhhhh\OneDrive\myDev\bokssam\testdb.db')  
    cur = conn.cursor()
    quary = '''create table test(
        title text,
        pubd text, 
        pus text,
        page integer,
        re integer)'''
    cur.execute(quary)
    conn.commit()
    conn.close()
 
if __name__ == '__main__':
    create_table()


## 데이터 입력
def data_insert():
    conn = sqlite3.connect(r'C:\Users\hhhhh\OneDrive\myDev\bokssam\testdb.db') 
    cur = conn.cursor()
    cur.execute("insert into test values('Do it! 점프 투 파이썬', '2019-06-02', '이지스퍼블리싱', 360, 1);")
    ins_sql = "insert into test values(?,?,?,?,?);"  # 동적쿼리
    cur.execute(ins_sql, ('혼자 공부하는 파이썬', '2019-93-14', '한빛미디어', 460, 1))
    books = [('모두의 데이터 분석 with 파이썬', '2019-04-19', '길벗', 308, 0), ('파이썬 웹 프로그래밍, 실전편', '2011-11-19', '한빛미디어', 488, 1)]
    cur.executemany(ins_sql, books)  # 동적쿼리에 리스트 내용 적용
    conn.commit()
    conn.close()

if __name__ == '__main__':
    data_insert()


## 조회 - select
def data_select():
    conn  = sqlite3.connect(r'C:\Users\hhhhh\OneDrive\myDev\bokssam\testdb.db')
    cur = conn.cursor()
    cur.execute('select * from test')
    rs = cur.fetchall()  # fetchone fetchmany
    for book in rs:
        print(book)
    
    conn.close()

if __name__ == '__main__':
    data_select()

def data_select_where(num):
    conn  = sqlite3.connect(r'C:\Users\hhhhh\OneDrive\myDev\bokssam\testdb.db')
    cur = conn.cursor()
    cur.execute('select * from test where title like "%파이썬%"')
    rs = cur.fetchmany(num)
    for book in rs:
        print(book)
    
    conn.close()

if __name__ == '__main__':
    data_select_where(2)  # 가져올 개수


## 데이터 업데이트
def data_update():
    conn  = sqlite3.connect(r'C:\Users\hhhhh\OneDrive\myDev\bokssam\testdb.db')
    cur = conn.cursor()
    quary = 'update test set title=? where title=?'
    cur.execute(quary, ('혼자 공부하는 파이썬(윤인성)', '혼자 공부하는 파이썬'))
    conn.commit()
    conn.close()

if __name__ == '__main__':
    data_update()


## 데이터 삭제
from bokssam.dbconn import getConn
def data_delete():
    conn  = getConn()
    cur = conn.cursor()
    quary = 'delete from test where title=?'
    cur.execute(quary, ('혼자 공부하는 파이썬(윤인성)',))  # 튜플 형태로 해야 함
    conn.commit()
    conn.close()

if __name__ == '__main__':
    data_delete()

 

■ mariadb 다루기

## mariadb 설치 https://mariadb.org/download/

## 설치 후 HeidiSQL 로 접속

## CREATE DATABASE pythondb;
## USE pythondb;
## CREATE TABLE test(naem VARCHAR(10), phone VARCHAR(15));
## DESC test;
## INSERT INTO test VALUES('홍길동', '010-1111-1111');

## Install MariaDB Connector/Python : pip install mariadb
## https://mariadb.com/docs/clients/mariadb-connectors/connector-python/

## mariadbconn.py
import mariadb

## 방법 1.
config = {
    'user': 'root',
    'password': 'qw1234',
    'host': '127.0.0.1',
    'database': 'pythondb',
    'port': 3306
}

def getConnection():
    try:
        conn = mariadb.connect(**config)
        return conn
    except Exception as e:
        print(e)

# conn = getConnection()
# print(conn)  # <mariadb.connection object at 0x00000262E455BB40



## 방법 2.
def getConn():
    try:
        conn = mariadb.connect(
            user = 'root',
            password = 'qw1234',
            host = 'localhost',
            database = 'pythondb',
            port = 3306
            )
        # print(conn)
        return conn
    except Exception as e:
        print(e)

# print(getConn())  # mariadb.connection object or None

 

from mariadbconn import getConnection

def create_table():
    conn = getConnection()
    print('conn:', conn)  
    # <mariadb.connection object at 0x0000016E87D9BCA0>  or None

    if conn:
        cur = conn.cursor()
        print('cur:', cur)  
        # <mariadb.connection.cursor object at 0x000002119A2DC310>
    else:
        print('db Error!!')

    # table 생성
    cur.execute(''' create table sj(
            name varchar(20),
            kor int,
            eng int,
            math int) ''')

    conn.commit()
    conn.close()

if __name__ == '__main__':
    create_table() 
    
    
## -------------------------------------------------------------------

from mariadbconn import getConnection

def insert_data():
    conn = getConnection()

    if conn:
        cur = conn.cursor()
    else:
        print('db Error!!')

    # insert
    quary = 'insert into sj values(%s, %s, %s, %s)'  # 동적 쿼리
    # cur.execute(quary, ('홍길동', 70, 80, 90))
    lst = [('김철수', 78, 88, 98), ('이영희', 90, 70, 90), ('임걱정', 100, 90, 90)]
    cur.executemany(quary, lst)
    conn.commit()
    conn.close()


if __name__ == '__main__':
    insert_data()

## -------------------------------------------------------------------

from mariadbconn import getConnection

def insert_data():
    conn = getConnection()

    if conn:
        cur = conn.cursor()
    else:
        print('db Error!!')

    # select
    cur.execute('select * from sj')
    rs = cur.fetchall()
    print(type(rs))  # <class 'list'>

    for s in rs:
        print(f'{s[0]} / {s[1]} / {s[2]} / {s[3]}')

    conn.commit()
    conn.close()


def insert_data1(name):
    conn = getConnection()
    cur = conn.cursor()
    cur.execute('select * from sj where name like %s', (name,))
    rs = cur.fetchone()  # fetchone()은 tuple, fetchall()은 list
    print(type(rs), rs)  # <class 'tuple'> ('이영희', 90, 70, 90)
    disp(rs)

    conn.close()


def disp(rs):
    tot = rs[1] + rs[2] + rs[3]
    avg = tot / 3
    print(f'총점: {tot}, 평균: {avg:.1f}')  # 총점: 250, 평균: 83.3


if __name__ == '__main__':
    insert_data()
    insert_data1('이영희')

## -------------------------------------------------------------------

from mariadbconn import getConnection

def update_data(name, grade):
    conn = getConnection()

    if conn:
        cur = conn.cursor()
    else:
        print('db Error!!')

    # update
    cur.execute('update sj set kor=%s where name=%s', (grade, name))
    conn.commit()
    conn.close()


if __name__ == '__main__':
    update_data('이영희', 100)

## -------------------------------------------------------------------

from mariadbconn import getConnection

def delete_data(name):
    conn = getConnection()

    if conn:
        cur = conn.cursor()
    else:
        print('db Error!!')

    # delete
    cur.execute('delete from sj where name=%s', (name,))
    conn.commit()
    conn.close()


if __name__ == '__main__':
    delete_data('이영희')

 

[출처] [소놀 코딩] 

 

댓글