Python

Python(12) 클래스

UserDonghu 2023. 9. 17. 19:47

클래스

설계 도면 또는 공장 같은 느낌

class Car: # 차의 설계 도면 또는 차 공장
    max_speed = 300
    max_people = 5
    car_gear = ['P', 'D', 'R', 'N']

    def start(self):
        print('차가 출발합니다!')

    def stop(self):
        print('차가 멈췄습니다!')

# 테슬라 공장에서 나온 자동차
# model x, y, s!
modelx = Car()
modely = Car()
models = Car()

# Car.max_speed # modelx의 속도를 보고 싶으면 modelx.max_speed를 찍어야 함

print(models.car_gear[1]) # D
models.start() # 차가 출발합니다!
models.stop() # 차가 멈췄습니다!

# int, float, str과 같은 새로운 Car라는 type을 만들고 있는 것

 

x = int(3)
# x 는 int라는 class의 인스턴스
# x = int(3) 여기서 넣었던 3이라는 값이 어떻게 처리되는지 확인
class Car:
    max_speed = 300
    max_people = 5
    car_gear = ['P', 'D', 'R', 'N']

    def __init__(self, name):
        self.name = name

    def start(self):
        print('차가 출발합니다!')

    def stop(self):
        print('차가 멈췄습니다!')

modelx = Car('Tesla Model X') # x = int(3) 여기서 넣었던 3이 __init__ 매직메서드에서 처리됨
print(modelx.name) # Tesla Model X

 

class Person:
    name = 'hu' # 클래스 변수
    def __init__(self, name):
        def hello():
            print('hello')
        hello()
        self.name = name # 인스턴스 변수

donghu = Person('donghu')
print(donghu.name)
print(Person.name)

# hello
# donghu
# hu

 

def hello():
    print('hello wolrd')

print(type(hello)) # <class 'function'>

hello.hi = 'hi, world'
print(hello.hi) # 'hi, world'

s = 10
s.hi = 'hi, world'
print(s.hi) # Error int, str, list, dict는 안됨

 

매직 메서드 (던더 메서드)

클래스 매직 메서드 만들어보기

class Point:

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Point((self.x + other.x), (self.y + other.y))

    def distance(self, other):
        dx = self.x - other.x
        dy = self.y - other.y
        return (dx**2 + dy**2)**0.5

dot1 = Point(10, 20)
dot2 = Point(20, 30)

dot3 = dot1 + dot2
print(dot3.x, dot3.y) # 30 50
dot3.distance(dot1) # 36.05551275463989

 

행렬 클래스 만들어보기

class Matrix:

    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        result = []
        for i in range(len(self.value)):
            result.append(self.value[i] + other.value[i])
        return result

    def __mul__(self, other):
        if isinstance(other, int):
            return [i*other for i in self.value]
        raise TypeError('int형 외 곱을 허락하지 않습니다.')

m1 = Matrix([10, 20, 30])
m2 = Matrix([20, 30, 40])

m1 * [1, 2] # Error 'int형 외 곱을 허락하지 않습니다.'
class Counter:
    
    def __init__(self):
        self.num = 0

    def __len__(self):
        return 100

    def __call__(self):
        return 'Hello'

    def __getitem__(self, key):
        return key*10

    def __str__(self):
        return 'hello'

    def __repr__(self):
        return 'world'

c = Counter()
print(len(c)) # 100
print(c()) # Hello # __call__
print(c[10]) # 100 # __getitem__
print(c) # print(str(c)) # hello
c # __repr__ # world

 

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

class Car:
    # 클래스 변수의 위치
    max_speed = 300
    max_people = 5
    car_gear = ['P', 'D', 'R', 'N']

modelx = Car()
modely = Car()

modely.max_speed = 500

print(Car.max_speed) # 300
print(modelx.max_speed) # 300
print(modely.max_speed) # 500(인스턴스 변수를 출력한 것)
class Car:
    # 클래스 변수의 위치
    max_speed = 300
    max_people = 5
    car_gear = ['P', 'D', 'R', 'N']

modelx = Car()
modely = Car()

modely.max_speed = 500

print(id(Car.max_speed)) # 135675434106928 id가 같음
print(id(modelx.max_speed)) # 135675434106928
print(id(modely.max_speed)) # 135675434113520 id가 다름. 값을 바꾸면 주소가 바뀜
class Car:
    kinds = []
    speed = 300

    def add_kinds(self, name):
        self.kinds.append(name)

    def change_speed(self, speed):
        self.speed = speed

modelx = Car()
modely = Car()

modelx.add_kinds('x')
modely.add_kinds('y')

Car.speed = 100

# modelx.change_speed(500)
# modely.change_speed(250)

print(f'modelx.kinds: {modelx.kinds}') # modelx.kinds: ['x', 'y']
print(f'modely.kinds: {modely.kinds}') # modely.kinds: ['x', 'y']
print(f'modelx.speed: {modelx.speed}') # modelx.speed: 100
print(f'modely.speed: {modely.speed}') # modely.speed: 100

 

kinds = [] # 전역변수 speed 300

def add_kinds(value):
    kinds.append(value) # 지역에 해당 변수가 없으므로 전역변수 kinds에 append

add_kinds(100)
print(kinds) # [100]
x = 100
def test():
    x = 200 # 값을 읽어올 수 있지만 변경은 안됨
    # x 는 전역변수를 건드리지 않고 지역변수 200을 선언했을 뿐
test()
print(x) # 100

x = 100
def test():
    global x # 전역변수 건드리려면 global
    x = 200 # 전역변수 x를 수정할 수 있게 됨
test()
print(x)

 

# 매우 중요
l = [10, 20, 30]
def test(ll):
    ll.append(40)

test(l)
print(l) # [10, 20, 30, 40]

i = 100
def test(ii):
    ii = 300

test(i)
print(i) # 100

 

클래스 상속

상속 하는 법

class A:
    def hello(self):
        return 'hello'

class B(A):
    def __init__(self, a):
        print(a)

    def world(self):
        return 'world'

b = B(10) # 10
print(b.hello()) # hello
print(b.world()) # world

오버라이딩

class A:
    def hello(self):
        return 'hello'

class B(A):
    def __init__(self, a):
        print(a)

    def world(self):
        return 'world'

    def hello(self): 
        return 'hello world'

b = B(10) # 10
print(b.hello()) # hello world # B의 hello가 A의 hello를 덮음

 

class A(object):
    def one(self):
        return 'one'

class B(A):
    def two(self):
        return 'two'

class C(B):
    def three(self):
        return 'three'

c = C()
print(c.one()) # one
print(c.two()) # two
print(c.three()) # three

 

상속 받을때 참조 값 주의

class A(object):
    test = 0
    def one(self):
        return 'one'

class B(A):
    def two(self):
        return 'two'

class C(B):
    def three(self):
        return 'three'

c = C()
A.test = 300
print(c.test) # 300 # 상속 받을때 참조 값으로 받음 주의

 

다중 상속

class A:
    def hello(self):
        print('hello A')

class B:
    def hello(self):
        print('hello B')

class C(A, B): # A 우선
    pass

c = C()
c.hello() # hello A

 

다이아몬드 상속

# 주의 2.x버전과 3.x버전의 아래 다이아몬드 상속 순서가 다름
class A:
    def hello(self):
        print('hello A')

class B(A):
    def hello(self):
        print('hello B')

class C(A):
    def hello(self):
        print('hello C')

class D(B, C):
    pass

d = D()
d.hello() # hello B
D.mro() # 뭘 먼저 상속받았는지 확인 가능 # [__main__.D, __main__.B, __main__.C, __main__.A, object]

'Python' 카테고리의 다른 글

Python(14) 모듈  (0) 2023.09.19
Python(13) 클래스 심화  (1) 2023.09.19
Python(11) if, match, for, while 문  (0) 2023.09.15
Python(10) 리스트 컴프리헨션, 삼항 연산자  (0) 2023.09.13
Python(9) 튜플, 딕셔너리, Set(집합)  (0) 2023.09.13