Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

BASEMENT

Python 4주차 - 1 본문

Programming/Python

Python 4주차 - 1

2_34 2020. 7. 12. 17:42

 

클래스 (Class)

1. 객체 지향 프로그래밍

 

클래스 기반의 프로그램을 작성

  • 클래스는 속성과 메서드를 하나로 묶어서 처리하는 캡슐화 성질을 가짐
  • 사용자 정의를 통해 새로운 객체(자료형)를 만들어서 사용 -> 인스턴스(instance) 생성

 

객체 지향의 성질

  • 객체 또는 인스턴스를 생성한 후 사용
  • 상속성 : 기존 class의 기능들을 다른 class에 상속 가능
  • 다형성 (오버로딩, 오버라이딩) : 상속받은 기능 수정 가능

2. 클래스

 

클래스의 구조

  • 현실 세계의 사물을 컴퓨터 안에서 구현하려고 고안된 개념
  • class 키워드 사용
  • 클래스 이름은 첫글자를 대문자로 지정 (함수와 구별 용이)
  • self 매개변수 : 각 인스턴스가 클래스의 속성과 메서드 등에 접근할 수 있게 해주는 권한 역할
class 클래스 이름:
	클래스 관련 코드 작성
Python

 

클래스의 예 - 자동차 클래스

 

class 자동차:

     # 자동차의 속성  -> 변수 생성 : 필드 (field)

        색상

        속도

     # 자동차의 기능 -> 함수 생성 / 클래스 내의 함수 : 메서드(method)

        속도 올리기()

        속도 내리기()

class Car:
    # 자동차 필드
    색상 = ''
    현재속도 = 0
    # 자동차 메서드
    def upSpeed(증가할 속도량):
    	# 속도 증가관련 코드 작성
    def downSpeed(감소할 속도량):
    	# 속도 감소관련 코드 작성
    
Python

class Car의 인스턴스를 생성하여 실행시키기

class Car:
	def color(self,car_color):
    	self.c_color = car_color
        
yellowCar = Car()   # 인스턴스 생성
yellowCar.color("yellow")    # 메서드 color 호출 및 c_color에 값 부여
print(yellowCar.c_color)     # 결과 : yellow

blueCar = Car()   
blueCar.color("blue")   
print(blueCar.c_color)       # 결과 : blue
Python

* self

인스턴스의 정보가 들어가는 매개변수

클래스 외부에서 필드를 인스턴스를 통해 사용하기 위해서 꼭 필요함

 

class Car:
	def color(self, car_color):    
    self.c_color = car_color    
    
   	def carPrint(self):       # 메서드 실행시 입력값이 없어도 self는 필요함
    	print("class Car")
        
yellowCar = Car()            
yellowCar.carPrint()
Python
class Car:
    def color(self,car_color):
        self.c_color = car_color
        self.carPrint()        # 클래스 내에서 함수 상호 호출 시에도 self 필요
    
    def carPrint(self):
        print("class Car")

yellowCar = Car()
yellowCar.color("yellow")
print(yellowCar.c_color)        # 결과 : class Car
                                #        yellow
Python

id를 이용한 self의 의미 확인

class EC:
    def f1():
        print("first function")
    def f2(self):
        print(id(self))
        print("second function")

if __name__ == "__main__":
    me = EC()
    print(id(me))
    me.f2()
    you = EC()
    print(id(you))
    you.f2()
Python

 인스턴스를 사용하지 않고 클래스 메서드로도 사용 가능 -> 잘 사용하진 않음

class EC:
    def f1():
        print("first function")
    def f2(self):
        print(id(self))
        print("second function")
        
if __name__ == "__main__":
	me = EC()
    EC.f1(me)                   # me.f1()시 에러
Python

3. 생성자 (Constructor)

  • 클래스 인스턴스 생성 시 자동으로 호출되는 메서드
  • 인스턴스 생성 시 필드(변수) 등의 초기값 설정
  • 생성자 기본 : Special Method 또는 Magic Method
  • 기본형태 : __init__(self)
class 클래스 이름:
	def __init__(self):
    	# 초기화할 코드 작성
Python
class Car:
    def __init__(self,speed):        # 생성자 함수
        self.speed = speed

    def upSpeed(self, up_value):
        self.speed += up_value
        if self.speed >= 150:
            self.speed = 150
    def color(self, car_color):
        self.c_colr = car_color

yellowCar = Car(30)                 # self.speed 30
yellowCar.upSpeed(200)
yellowCar.color = "yellow"
print(yellowCar.speed, yellowCar.color)    # 150 yellow
Python
class Car:
    def __init__(self, colorV, speedV):     # 인스턴스 별 필드의 초기값 설정 가능
        self.c_color = colorV
        self.speed = speedV
    def upSpeed(self, up_value):
        self.speed = up_value
    def downSpeed(self, down_value):
        self.speed = down_value
    def color(self, car_color):
        self.c_color = car_color

redCar = Car("red",10)
blueCar = Car("blue",20)
print(redCar.c_color, redCar.speed)
print(blueCar.c_color, blueCar.speed)
Python

예제 

Point 클래스는 생성자를 통해 (x,y) 좌표를 입력 

setx(x), sety(y) 메서드를 통해 x좌표와 y좌표를 따로 입력

get() 메서드를 호출하면 튜플로 구성된 (x,y) 좌표 반환

movexy(dx,dy) 메서드는 현재 좌표를 dx, dy만큼 이동

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def setx(self, x):
        self.x = x
    def sety(self, y):
        self.y = y
    def getxy(self):
        return self.x, self.y
    def movexy(self, mx, my):
        self.x += mx
        self.y += my

mypoint = Point(0,0)
print(mypoint.getxy())
mypoint.setx(10)
mypoint.sety(30)
print(mypoint.getxy())
mypoint.movexy(10,-5)
print(mypoint.getxy())
Python

4. 네임스페이스 (namespace)

 

변수가 객체를 바인딩할 때 그 둘 사이의 관계를 저장하고 있는 공간을 의미함

ex) a = 2 -> #2 라는 객체가 저장된 주소를 a가 가지고 있으며 이러한 연결 관계가 저장된 공간 (네임스페이스)

 

  • 파이썬 클래스는 하나의 네임스페이스를 가짐
  • dir() 함수로 객체에 정의된 식별자(함수, 변수 등) 확인
  • __dict__ : 해당되는 개체의 속성들을 딕셔너리형태로 확인
  • 클래스가 정의되면 독립적인 네임스페이스가 생성됨
class Country:
	local = "Seoul"
Country.__dict__
Python
class Country:
    local = "Seoul"

if __name__ == '__main__':
    me = Country()              # 인스턴스 생성만 한 상태
    you = Country()
    print(me.__dict__)          # 딕셔너리 비어 있음
    print(you.__dict__)         # me.local -> Seoul / you.local -> Seoul
Python
class Country:
    local = "Seoul"
    def addr(self, *others):       # *others : 가변 매개변수
        self.local, self.gu, self.load = others

if __name__ == "__main__":
    me = Country()
    print(Country.__dict__)
    print(me.__dict__)
    me.addr('부산','해운대','해운대로')
    print(me.__dict__)
    print(f'{me.local}{me.gu}{me.load}')

5. 인스턴스 변수와 클래스 변수

 

1) 인스턴스 변수

  • 인스턴스 생성 시 사용할 수 있는 변수
  • 클래스 내에 선언된 인스턴스 변수는 실제 공간이 할당되지 않음 -> 인스턴스 생성 시 공간 할당됨
  • 인스턴스 변수 예
class Car:
	def __init__(self):
    	self.color = ""
        self.speed = 0
        
redCar = Car()             # 인스턴스 생성. color, speed 공간 할당
redCar.color = "red"
redCar.speed = 100

 

2) 클래스 변수

  • 클래스 내에 저장공간이 할당된 변수
  • 한 클래스의 여러 인스턴스들 사이의 전역변수 역할 -> 클래스 변수 공간을 공동으로 사용
  • 클래스 변수 생성은 인스턴스 변수 생성과 동일
  • 사용 시 클래스명.클래스변수명 or 인스턴스.클래스변수명

클래스 변수 사용 예

class Country:
    local = "서울"                     # 클래스 변수
    print(f'id of local: {id(local)}')
    def addr(self, *others):
        self.gu, self.load = others
        print(f'id of self.local: {id(self.local)}')  # 인스턴스 필드가 없으므로 클래스 변수와 같음

if __name__ == "__main__":
    me = Country()
    you = Country()
    me.addr('영등포구', '선유로')
    print(f'id of me.local: {id(me.local)}')      # 클래스 변수와 같음    
    print(f'id of you.local: {id(you.local)}')    # 클래스 변수와 같음
    print(f'id of me.local: {id(Country.local)}') # 클래스 변수와 같음   
class Country:
    local = "서울"
    print(f'id of local: {id(local)}')
    def addr(self, *others):
        self.gu, self.load = others

if __name__ == "__main__":
    me = Country()
    you = Country()
    me.addr('영등포구', '선유로')
    you.addr('종로구', '인사동길')

    print(me.local, me.gu, me.load)           # 서울 영등포구 선유로
    print(you.local, you.gu, you.load)        # 서울 종로구 인사동길
    print(f'{id(me.gu), id(you.gu)}')
Python

클래스 변수 사용 예

class Car:
    count = 0       # 클래스 변수
    def __init__(self, colorV, speedV):
        self.color = colorV
        self.speed = speedV
        Car.count += 1          # self.count += 1 로 변경시 값은 1

greenCar, redCar = None, None
greenCar = Car("green", 60)
print("greenCar의 색상은 {}, 속도는 {}, 생산 댓수는 {}".format(greenCar.color, greenCar.speed, greenCar.count))
redCar = Car("red", 80)
print("redCar의 색상은 {}, 속도는 {}, 생산 댓수는 {}".format(redCar.color, redCar.speed, redCar.count))
Python
class Car:
    def __init__(self, colorV, speedV):
        self.color = colorV
        self.speed = speedV
    def localV(self):
        count = 10    # local 변수. 필드로 하고 싶다면 self.count로 변경
        return count

redCar = None
redCar = Car("red", 80)

main_c = redCar.localV()      # 메인코드에서 local 변수 count 출력
print("main_c: ", main_c)
Python

6. 클래스 상속 (Inheritance)

 

상속의 개념

  • 기존 클래스(부모클래스)에 있는 필드 및 메서드 등의 성질을 그대로 물려받은 새로운 클래스(자식클래스)를 생성

상속받는 클래스 생성 과정

  • 공통된 내용을 담은 클래스 생성 (부모 클래스)
  • 공통된 내용 + 변형된 내용을 담은 클래스 생성 (자식 클래스)
  • ex) 차의 공통된 성질로 구성된 자동차 클래스 생성 -> 차의 공통성질
  •      + 차 종류에 따른 차별화 성질로 구성된 승용차, 트럭, 버스 등의 클래스 생성
class 부모클래스 또는 슈퍼 클래스:

       #코드

class 자식클래스 또는 서브클래스(부모클래스명):

       #코드
Python
class Car:
	def __init__(self, colorV,speedV):
    	self.color = colorV
        self.speed = speedV
        
class Sedan(Car):
	def carNum(self,num):
    	self.number = num

myCar = Sedan("yellow", 150)
print(myCar.color, myCar.speed)
myCar.carNum(5)
print(myCar.number)
Python

 

자식 클래스에 별도의 생성함수가 부모 클래스의 생성함수 이용 시

super(). 사용

class Car:
    count = 0
    def __init__(self, colorV, speedV):
        self.color = colorV
        self.speed = speedV
        Car.count += 1

class Sedan(Car):
    def __init__(self, colorV, speedV, numV):
        super().__init__(colorV, speedV)      # super(). 사용 -> self는 작성하지 않음
        self.number = numV

myCar = Sedan("red", 120, 5)
print("myCar는 색상은 {}, 속도는 {}, 승차인원은 {}, 차의 생산댓수는 {}".format(myCar.color,myCar.speed,myCar.number,Car.count))
Python

7. 메서드 오버라이딩 (Overriding)

 

상위 클래스의 메서드를 서브 클래스에서 재정의하는 것

ex) 속도 올리기에서 승용차 클래스는 150이상 불가한 경우

 

__init__ 메서드 오버라이딩 예제

class Car:
    def __init__(self, colorV, speedV):
        self.color = colorV
        self.speed = speedV
    def upSpeed(self, plus):
        self.speed += plus

class Sedan(Car):
    def __init__(self, colorV, speedV, doorV):
        super().__init__(colorV, speedV)
        self.door = doorV

me = Sedan("green", 80, 4)
print("초기 속도: %d" % me.speed)
me.upSpeed(100)
print("업 속도: %d" % me.speed)           # 결과 -> 초기 속도: 80, 업 속도 : 180
Python

upSpeed 메서드 오버라이딩 적용된 경우 예제

class Car:
    def __init__(self, colorV, speedV):
        self.color = colorV
        self.speed = speedV
    def upSpeed(self, plus):
        self.speed += plus

class Sedan(Car):
    def __init__(self, colorV, speedV, doorV):
        super().__init__(colorV, speedV)
        self.door = doorV
    def upSpeed(self, plus):
        self.speed += plus
        if self.speed >= 150:
            self.speed = 150

me = Sedan("green", 80, 4)
print("초기 속도: %d" % me.speed)
me.upSpeed(100)
print("업 속도: %d" % me.speed)          # 결과 -> 초기속도: 80 업속도: 150
Python

Car -> Sedan -> Sona 클래스 생성 (상속의 상속)

class Car:
    def __init__(self, colorV, speedV):
        self.color = colorV
        self.speed = speedV
    def upSpeed(self, plus):
        self.speed += plus

class Sedan(Car):
    def __init__(self, colorV, speedV, doorV):
        super().__init__(colorV, speedV)
        self.door = doorV
    def upSpeed(self, plus):
        super().upSpeed(plus)
        if self.speed >= 150:
            self.speed = 150

class Sona(Sedan):
    def __init__(self, colorV, speedV, doorV, coV):
        super().__init__(colorV,speedV,doorV)
        self.company = coV

me = Sona("green", 50, 2 ,"Hyun")
print("초기 속도: %d, 도어 수: %d" % (me.speed, me.door))
print("생산회사: %s" % me.company)
me.upSpeed(200)
print("업 속도: %d" % me.speed)
Python

 

8. 접근성 (access)

 

객체의 정보를 볼 수 있는 레벨을 조절 -> 객체의 정보 접근을 숨기는 것

캡슐화 (encapsulation) 또는 정보 은닉 (information hiding)

  • 객체의 매개 변수 인터페이스만 명확하게 알면 사용

파이썬은 일반 객체지향 언어가 가지는 자원(필드, 메서드) 접근 권한에 대한 접근 지정자가 없음

-> public, private, protected등

자원 접근 권한에 대한 규칙으로 대신함

  • 자원 이름 앞에 _ 또는 __ 를 사용하여 접근권한을 명시적으로 표시
  • _ (single underscore) : protected, 클래스 내 또는 상속받은 클래스 내에서 사용
  • __ (double underscore) : private, 선언된 클래스 내에서만 사용 (자식 클래스에서도 사용 불가)

 

single underscore 예제

실제적으로는 외부 접근 가능하나, 코드 작성자는 외부 접근 코드를 작성하지 않음

class Employee:
    def __init__(self, name, sal):
        self._name = name          # protected attribute
        self._salary = sal         # protected attribute
    def _access(self, num):
        self.result = sum(num)
        self.total = self._salary + self.result

class Bank_employee(Employee):
    def bank_salary(self,tax):
        self._tax = tax
        self._pay = self._salary * self._tax

if __name__ == '__main__':
    me = Bank_employee('Yoon', 300000)
    me._access([1000,2000,4000])
    print(f'{me.total}')
    print(f'{me._name}, {me._salary}')
Python

double underscore 예제

상속된 자식 클래스 및 외부에서의 접근 불가, 오류 발생

class Employee:
    def __init__(self, name, sal):
        self._name = name               # protected attribute
        self.__salary = sal             # private attribute

    def __access(self, num):            # private method
        self._num = num
        self.result = sum(self._num)
        self.total = self.__salary + self.result

class Bank_employee(Employee):
    def bank_salary(self,tax):
        self._tax = tax
        self._pay = self.__salary * self._tax

if __name__ == '__main__':
    me = Bank_employee('Yoon', 300000)
    me._access([1000,2000,4000])
    print(f'{me.total}')
    print(f'{me._name}, {me._salary}')
    me.bank_salary(0.01)
    print(f'{me._pay}')
Python

-> 실제로 private 때문에 오류가 발생하는 것은 아님. 네임 맹글링 때문에 오류 발생

 

9. 네임 맹글링

  • 이중밑줄은 클래스 속성에 사용 시 단일밑줄과 차이점이 있음
  • 네임 맹글링 적용
  • 네임 맹글링 : C++에서 컴파일러가 함수, 변수 등의 이름을 임의로 지정된 규칙으로 변경하여 컴파일 하는 것
class Test:
    def __init__(self):
        self.var = 10
        self._num = 30
        self.__mangling = 50

op = Test()
print(f'{op.var}')
print(f'{op._num}')
print(f'{op._Test__mangling}')   # op.__mangling 입력시 오류. print(op.__dict__)로 확인하기
Python

10. 가시성 (visibility)

 

private로 지정된 attribute를 외부에서 접근하기 위한 방법

  • 외부에서 접근하기 위해서는 클래스에서 메서드를 통해 속성의 값을 가져오거나 저장하는 방식 활용
  • @property 적용 (파이썬에서 @가 붙은 예약어는 데코레이터라 함)

값을 할당하고(setter), 할당된 값을 가져오는 메서드(getter) 구현을 통해 private 속성 값을 외부에서 할당하고 전달 가능

class Person:
    def __init__(self):
        self.__age = 0

    @property
    def age(self):              # getter
        return self.__age
    @age.setter                 # @property의 메소드 age / @메소드.setter 
    def abc(self,years):
        self.__age = years

korea = Person()
korea.abc = 20
print(f'{korea.age}')

@property 데코레이터 예제

class InfoClass:
    def __init__(self):
        self.__name = "Python"
        self.__weekday = "수요일"
    
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self, name):
        self.__name = name
    
    @property
    def weekday(self):
        return self.__weekday
    @weekday.setter
    def weekday(self, weekday):
        self.__weekday = weekday

if __name__ == "__main__":
    class1 = InfoClass()
    class1.name = "Data Design"
    print(class1.name)
    class1.weekday = "금요일"
    print(class1.weekday)
Python

11. 클래스의 특별한 메서드

 

1) __del__()

  • 소멸자로 인스턴스 삭제 시 자동 실행
  • 인스턴스 소멸 : del(인스턴스 이름)
  • 특별한 동작 필요 : __del__ 함수에 작성
class Product:
    def __init__(self, itemV, priceV, pieceV):
        self.item = itemV
        self.price = priceV
        self.piece = pieceV
    def cal_cost(self):
        self.total = self.price*self.piece
        return self.total
    
    def __del__(self):						
        print("product instance extinction")

book = None
book = Product("book", 12000, 3)
print("book's cost: %d" % book.cal_cost())		# book's cost: 36000
del(book)						# product instance extinction

2. __repr__()

 

인스턴스를 print 문으로 출력할 때 실행

class Line:
    length = 0
    def __init__(self, lenV):
        self.length = lenV
        print("%d Line 인스턴스 생성" % self.length)		# 200 Line 인스턴스 생성
    								# 400 Line 인스턴스 생성
    def __repr__(self):
        return '선의 길이 : ' + str(self.length)

myL1, myL2 = None, None
myL1 = Line(200)
myL2 = Line(400)
print(myL1)			# 선의 길이 : 200
print(myL2)			# 선의 길이 : 400

3. __add__()

 

인스턴스 사이의 덧셈 작업이 일어날 때 실행

class Line:
    length = 0
    def __init__(self, lenV):
        self.length = lenV
        print("%d Line 인스턴스 생성" % self.length)
    
    def __add__(self, other):
        return self.length + other.length

myL1, myL2 = None, None
myL1 = Line(200)
myL2 = Line(400)
print('두 선의 길이 합 : ', myL1+myL2)		# 두 선의 길이 합 :  600

4. 비교 - __lt__(), __le__(), __gt__(), __ge__(), __eq__(), __ne__()

 

인스턴스 사이의 비교 연산자를 사용할 때 호출

class Line:
    length = 0
    def __init__(self, lenV):
        self.length = lenV
        print("%d Line 인스턴스 생성" % self.length)
    
    def __lt__(self, other):
        return self.length < other.length
    def __eq__(self, other):
        return self.length == other.length

myL1, myL2 = None, None
myL1 = Line(200)
myL2 = Line(400)
if myL1 < myL2:						# myL2의 선분이 더 깁니다
    print('myL2의 선분이 더 깁니다')
elif myL1 == myL2:
    print('myL1 == myL2 입니다')
else:
    print('myL1의 선분이 더 깁니다')

12. 추상 메서드

 

오버라이딩을 위한 부모 클래스 내의 빈 껍질 메서드

반드시 자식 클래스 내에서 오버라이딩을 해야 함

class Parents:
    def method(self):
        pass		# pass : 함수 미정일 때 오류를 방지하기 위함

class Child1(Parents):
    def method(self):
        print("Child1에서 method를 오버라이딩")

class Child2(Parents):
    def method(self):
        print("Child2에서 method를 오버라이딩")

sub1 = Child1()    
sub2 = Child2()
sub1.method()		# Child1에서 method를 오버라이딩
sub2.method()		# Child2에서 method를 오버라이딩 
class Parents:
    def method(self):
        raise NotImplementedError()		# raise : 예외를 강제로 발생시킴

class Child1(Parents):
    def method(self):
        print("Child1에서 method를 오버라이딩")

class Child2(Parents):
        pass					

sub1 = Child1()    
sub2 = Child2()
sub1.method()
sub2.method()					# Child2 자식클래스를 생성하지 않아서 오류를 발생시킴 

13. 클래스 다중상속

 

클래스 다중 상속시, 먼저 작성된 클래스의 생성자 함수를 실행함

class Car:
    speed = 0
    def __init__(self, color, shape):
        self.color = color
        self.shape = shape
        print("{}와 {}의 차입니다".format(self.color, self.shape))
    
    def speedup(self, speed):
        self.speed += speed
    def speeddown(self, speed):
        self.speed -= speed

class SemiSelfCar:
    def __init__(self, option):
        self.option = option
        print("%d 옵션입니다" % self.option)

    def ADAS(self, control):
        self.control = control
        if self.control == 'stop':
            print("Step on the brake")
        elif self.control == 'accel':
            print("Step on the accel")
        else:
            print("Control fail")

class SelfDrivingCar(Car, SemiSelfCar):		# 생성자함수 : Car의 생성자 함수
    def auto_map(self):
        print("printing auto_map")
    def auto_run(self):
        print("{} 속도로 자율 주행합니다".format(self.speed))

auto1 = SelfDrivingCar("green", "Sedan")
auto1.speedup(30)
auto1.auto_run()		# green와 Sedan의 차입니다
				# 30 속도로 자율 주행합니다
# 예제 - 클래스 내 클래스
# Play 클래스가 삭제되면 Customer 클래스 오류 발생 -> 클래스 종속 관계

class Customer:
    def __init__(self, name, num):
        self.name = name
        self.num =num
    def book(self, play, place):
        self.play = Play(play, place)	# Customer 클래스 내에 Play 클래스 사용
    def classPoint(self, point, name):
        self.play.p_point(point)

class Play:
    points = {}
    def __init__(self, name, place):
        self.p_name = name
        self.place = place
    
    def p_point(self, point):
        if self.p_name in Play.points:
            Play.points[self.p_name] += point
        else:
            Play.points[self.p_name] = point
    
    def point_print(self):
        print(f'{self.p_name}의 평점 : {Play.points[self.p_name]}')

if __name__ == '__main__':
    c1 = Customer('Gildong', '123')
    c1.book('Rent', 'ArtCenter')
    c1.classPoint(5, 'Rent')
    c2 = Customer('Jane', '124')
    c2.book('Rent', 'ArtCenter')
    c2.classPoint(3, 'Rent')
    c3 = Customer('Yuna', '125')
    c3.book('Dracula', 'Sejong')
    c3.classPoint(4, 'Dracula')

    p1 = Play('Rent', 'ArtCenter')
    p1.point_print()		# Rent의 평점 :  8
    p2 = Play('Dracula', 'Sejong')
    p2.point_print()		# Dracula의 평점 : 4

'Programming > Python' 카테고리의 다른 글

Python 5주차  (0) 2020.07.26
Python 4주차 - 2  (0) 2020.07.12
Python 3주차 - 2  (0) 2020.07.12
Python 3주차 - 1  (0) 2020.07.12
Python 2주차 - 2  (0) 2020.07.11
Comments