[미래유망 2025-03-28]

돼지인간·2025년 3월 28일

미래유망

목록 보기
5/41

어제 클래스와 관련한 예제를 풀다가 다른 개념을 발견했다.
한번 정리해보도록 하겠다.

클로저

클로저는 간단히 말해 함수 안에 내부 함수를 구현하고 그 내부 함수를 리턴하는 함수를 말한다. 이때 외부 함수는 자신이 가진 변숫값 등을 내부 함수에 전달할 수 있다.

class Mul:

  def __init__(self, m):
    self.m = m
  
  def __call__(self, n):
    return self.m * n
  
if __name__ == "__main__":
  mul3 = Mul(3)
  mul5 = Mul(5)

  print(mul3(10))
  
  
  print(mul5(10))

또는

def mul(m):
    def wrapper(n):
        return m * n
    return wrapper

if __name__ == "__main__":
    mul3 = mul(3)
    mul5 = mul(5)

    print(mul3(10))  # 30 출력
    print(mul5(10))  # 50 출력

데코레이터

decorate는 꾸미다, 장식하다라는 뜻이므로 데코레이터를 함수를 꾸미는 함수라고 생각해도 된다.파이썬은 함수 위에 @+함수명이 있으면 데코레이터 함수로 인식한다.

import time

def elapsed(original_func):   # 기존 함수를 인수로 받는다.
    def wrapper():
        start = time.time()
        result = original_func()    # 기존 함수를 수행한다.
        end = time.time()
        print("함수 수행시간: %f 초" % (end - start))  # 기존 함수의 수행시간을 출력한다.
        return result  # 기존 함수의 수행 결과를 리턴한다.
    return wrapper

@elapsed
def myfunc():
    print("함수가 실행됩니다.")

클래스와 관련된 예제 풀어보기

Account 인스턴스에 저장된 정보를 출력하는 display_info() 메서드를 추가하세요. 잔고는 세자리마다 쉼표를 출력하세요.

import random
class Account:
  account_count = 0
  def __init__ (self, name, money):
    self.name = name
    self.money = money
    self.bank = "SC은행"

    num1 = random.randint(0, 999) # 3자리 수 랜덤 생성
    num2 = random.randint(0, 99) # 2자리 수 랜덤 생성
    num3 = random.randint(0, 999999) # 6자리 수 랜덤 생성

    # .zfill(숫자) 빈 자리를 0으로 채워줌
    num1 = str(num1).zfill(3)      # 1 -> '1' -> '001'
    num2 = str(num2).zfill(2)      # 1 -> '1' -> '01'
    num3 = str(num3).zfill(6)      # 1 -> '1' -> '0000001'
    self.num = num1 + '-' + num2 + '-' + num3 # num에 세개의 랜덤 num을 더한 값을 넣어줌

    Account.account_count += 1

  @classmethod # @classmethod에서는 cls인자를 활용하여 cls의 클래스속성을 가져오는 것
  def get_account_num(cls):
    print(cls.account_count)  # Account.account_count

  def deposit(self, plusMoney):
    if plusMoney >= 1:
      self.money += plusMoney


  def withdraw(self, minusMoney):
    if self.money > minusMoney:
      self.money -= minusMoney
    else:
      print("출금할 수 없습니다")
  
  def display_info(self):
    print(f"은행이름 : {self.bank}")
    print(f"예금주 : {self.name}")
    print(f"계좌번호 : {self.num}")
    print(f"잔고 : {self.money:,}원")


kim = Account("김민수", 100)
kim.deposit(50000)
kim.display_info()


입금 횟수가 5회가 될 때 잔고를 기준으로 1%의 이자가 잔고에 추가되도록 코드를 변경해보세요.

import random
class Account:
  account_count = 0
  def __init__ (self, name, money):
    self.name = name
    self.money = money
    self.bank = "SC은행"

    num1 = random.randint(0, 999) # 3자리 수 랜덤 생성
    num2 = random.randint(0, 99) # 2자리 수 랜덤 생성
    num3 = random.randint(0, 999999) # 6자리 수 랜덤 생성

    # .zfill(숫자) 빈 자리를 0으로 채워줌
    num1 = str(num1).zfill(3)      # 1 -> '1' -> '001'
    num2 = str(num2).zfill(2)      # 1 -> '1' -> '01'
    num3 = str(num3).zfill(6)      # 1 -> '1' -> '0000001'
    self.num = num1 + '-' + num2 + '-' + num3 # num에 세개의 랜덤 num을 더한 값을 넣어줌

    self.count = 1

    Account.account_count += 1

  @classmethod
  def get_account_num(cls):
    print(cls.account_count)  # Account.account_count

  def deposit(self, plusMoney):
    self.count += 1
    if plusMoney >= 1:
      self.money += plusMoney
    else : 
      print("입급할려는 금액이 1원 이하입니다.")
      
    if(self.count > 5):
      self.count = 1
      self.money += int(self.money * 0.01)


  def withdraw(self, minusMoney):
    if self.money > minusMoney:
      self.money -= minusMoney
    else:
      print("출금할 수 없습니다")
  
  def display_info(self):
    print(f"은행이름 : {self.bank}")
    print(f"예금주 : {self.name}")
    print(f"계좌번호 : {self.num}")
    print(f"잔고 : {self.money:,}원")


kim = Account("김민수", 0)
kim.deposit(100)
kim.deposit(100)
kim.deposit(100)
kim.deposit(100)
kim.deposit(100)
kim.display_info()


Account 클래스로부터 3개 이상 인스턴스를 생성하고 생성된 인스턴스를 리스트에 저장해보세요.

import random
class Account:
  account_count = 0
  def __init__ (self, name, money):
    self.name = name
    self.money = money
    self.bank = "SC은행"

    num1 = random.randint(0, 999) # 3자리 수 랜덤 생성
    num2 = random.randint(0, 99) # 2자리 수 랜덤 생성
    num3 = random.randint(0, 999999) # 6자리 수 랜덤 생성

    # .zfill(숫자) 빈 자리를 0으로 채워줌
    num1 = str(num1).zfill(3)      # 1 -> '1' -> '001'
    num2 = str(num2).zfill(2)      # 1 -> '1' -> '01'
    num3 = str(num3).zfill(6)      # 1 -> '1' -> '0000001'
    self.num = num1 + '-' + num2 + '-' + num3 # num에 세개의 랜덤 num을 더한 값을 넣어줌

    self.count = 1

    Account.account_count += 1

  @classmethod
  def get_account_num(cls):
    print(cls.account_count)  # Account.account_count

  def deposit(self, plusMoney):
    self.count += 1
    if plusMoney >= 1:
      self.money += plusMoney
    else : 
      print("입급할려는 금액이 1원 이하입니다.")

    if(self.count > 5):
      self.count = 1
      self.money += int(self.money * 0.01)


  def withdraw(self, minusMoney):
    if self.money > minusMoney:
      self.money -= minusMoney
    else:
      print("출금할 수 없습니다")
  
  def display_info(self):
    print(f"은행이름 : {self.bank}")
    print(f"예금주 : {self.name}")
    print(f"계좌번호 : {self.num}")
    print(f"잔고 : {self.money:,}원")


kim = Account("김민수", 500)
kim.display_info()

kang = Account("강이수", 10000)
kang.display_info()

jang = Account("장상호랑이", 1000)
jang.display_info()

accountLIst = [kim, kang, jang]


반복문을 통해 리스트에 있는 객체를 순회하면서 잔고가 100만원 이상인 고객의 정보만 출력하세요.

import random
class Account:
  account_count = 0
  def __init__ (self, name, money):
    self.name = name
    self.money = money
    self.bank = "SC은행"

    num1 = random.randint(0, 999) # 3자리 수 랜덤 생성
    num2 = random.randint(0, 99) # 2자리 수 랜덤 생성
    num3 = random.randint(0, 999999) # 6자리 수 랜덤 생성

    # .zfill(숫자) 빈 자리를 0으로 채워줌
    num1 = str(num1).zfill(3)      # 1 -> '1' -> '001'
    num2 = str(num2).zfill(2)      # 1 -> '1' -> '01'
    num3 = str(num3).zfill(6)      # 1 -> '1' -> '0000001'
    self.num = num1 + '-' + num2 + '-' + num3 # num에 세개의 랜덤 num을 더한 값을 넣어줌

    self.count = 1

    Account.account_count += 1

  @classmethod
  def get_account_num(cls):
    print(cls.account_count)  # Account.account_count

  def deposit(self, plusMoney):
    self.count += 1
    if plusMoney >= 1:
      self.money += plusMoney
    else : 
      print("입급할려는 금액이 1원 이하입니다.")

    if(self.count > 5):
      self.count = 1
      self.money += int(self.money * 0.01)


  def withdraw(self, minusMoney):
    if self.money > minusMoney:
      self.money -= minusMoney
    else:
      print("출금할 수 없습니다")
  
  def display_info(self):
    print(f"은행이름 : {self.bank}")
    print(f"예금주 : {self.name}")
    print(f"계좌번호 : {self.num}")
    print(f"잔고 : {self.money:,}원")


kim = Account("김민수", 500)
kang = Account("강이수", 10000)
jang = Account("장상호랑이", 2000000)

accountLIst = [kim, kang, jang]

for i in accountLIst:
  if i.money > 1000000:
    i.display_info()


입금과 출금 내역이 기록되도록 코드를 업데이트 하세요. 입금 내역과 출금 내역을 출력하는 deposit_historywithdraw_history 메서드를 추가하세요.

import random
class Account:
  account_count = 0
  def __init__ (self, name, money):
    self.name = name
    self.money = money
    self.bank = "SC은행"

    num1 = random.randint(0, 999) # 3자리 수 랜덤 생성
    num2 = random.randint(0, 99) # 2자리 수 랜덤 생성
    num3 = random.randint(0, 999999) # 6자리 수 랜덤 생성

    # .zfill(숫자) 빈 자리를 0으로 채워줌
    num1 = str(num1).zfill(3)      # 1 -> '1' -> '001'
    num2 = str(num2).zfill(2)      # 1 -> '1' -> '01'
    num3 = str(num3).zfill(6)      # 1 -> '1' -> '0000001'
    self.num = num1 + '-' + num2 + '-' + num3 # num에 세개의 랜덤 num을 더한 값을 넣어줌

    self.count = 1
    self.depositList = []
    self.withdrawList = []

    Account.account_count += 1

  @classmethod
  def get_account_num(cls):
    print(cls.account_count)  # Account.account_count

  def deposit(self, plusMoney):
    self.plusMoney = plusMoney
    self.count += 1
    if plusMoney >= 1:
      self.money += plusMoney
      self.depositList.append(self.plusMoney)
    else : 
      print("입급할려는 금액이 1원 이하입니다.")

    if(self.count > 5):
      self.count = 1
      self.money += int(self.money * 0.01)


  def withdraw(self, minusMoney):
    self.minusMoney = minusMoney
    if self.money > minusMoney:
      self.money -= minusMoney
      self.withdrawList.append(self.minusMoney)
    else:
      print("출금할 수 없습니다")
  
  def display_info(self):
    print(f"은행이름 : {self.bank}")
    print(f"예금주 : {self.name}")
    print(f"계좌번호 : {self.num}")
    print(f"잔고 : {self.money:,}원")

  def deposit_history(self):
    for i in self.depositList:
      print(f"{i:,}원을 입금했습니다.")

  def withdraw_history(self):
    for i in self.withdrawList:
      print(f"{i:,}원을 출금했습니다.")
    


kim = Account("김민수", 500)
kim.deposit(500)
kim.deposit(500)
kim.deposit(100)
kim.withdraw(500)
kim.deposit_history()
kim.withdraw_history()


다음 코드가 동작하도록 차 클래스를 정의하세요.

>> car =(2, 1000)
>> car.바퀴
2
>> car.가격
1000

답 :

class Car:
  def __init__(self, wheel, price):
    self.wheel = wheel
    self.price = price

car = Car(2, 1000)
print(car.wheel)
print(car.price)


차 클래스를 상속받은 자전차 클래스를 정의하세요.

class Car:
  def __init__(self, wheel, price):
    self.wheel = wheel
    self.price = price

class Bicycle(Car) : 
  pass

bicycle = Bicycle(2, 100)
print(bicycle.wheel)
print(bicycle.price)


다음 코드가 동작하도록 자전차 클래스를 정의하세요. 단 자전차 클래스는 차 클래스를 상속받습니다.

class Car:
  def __init__(self, wheel, price):
    self.wheel = wheel
    self.price = price

class Bicycle(Car) : 
  def __init__ (self, wheel, price):
    self.wheel = wheel
    self.price = price

bicycle = Bicycle(2, 100)
print(bicycle.price)


다음 코드가 동작하도록 자전차 클래스를 정의하세요. 단 자전차 클래스는 차 클래스를 상속받습니다.

class Car:
  def __init__(self, wheel, price):
    self.wheel = wheel
    self.price = price

class Bicycle(Car) : 
  def __init__ (self, wheel, price, bicycleName):
    super().__init__(wheel, price) # super()로 상속 대신 가능
    self.bicycleName = bicycleName

bicycle = Bicycle(2, 100, "시마노")
print(bicycle.bicycleName)


다음 코드가 동작하도록 차 클래스를 상속받는 자동차 클래스를 정의하세요.

class Car:
  def __init__(self, wheel, price):
    self.wheel = wheel
    self.price = price

class SportCar(Car) : 
  def __init__(self, wheel, price):
    super().__init__ (wheel, price)

  def info(self) : 
    print(f"바퀴 수 : {self.wheel}")
    print(f"가격 : {self.price}")

car = SportCar(4, 1000)
car.info()


다음 코드가 동작하도록 차 클래스를 수정하세요.

class Car:
  def __init__(self, wheel, price):
    self.wheel = wheel
    self.price = price
    
  def info(self) : 
    print(f"바퀴 수 : {self.wheel}")
    print(f"가격 : {self.price}")

class Bicycle(Car) : 
  def __init__ (self, wheel, price, name):
    super().__init__ (wheel, price)
    self.name = name

class SportCar(Car) : 
  def __init__(self, wheel, price):
    super().__init__ (wheel, price)

bicycle = Bicycle(2, 100, "시마노")
bicycle.info()


자전차의 정보() 메서드로 구동계 정보까지 출력하도록 수정해보세요.

class Car:
  def __init__(self, wheel, price):
    self.wheel = wheel
    self.price = price
    
  def info(self) : 
    print(f"바퀴 수 : {self.wheel}")
    print(f"가격 : {self.price}")

class Bicycle(Car) : 
  def __init__ (self, wheel, price, name):
    super().__init__ (wheel, price)
    self.name = name

  def info(self):
    super().info()
    print(f"구동계 : {self.name}")

class SportCar(Car) : 
  def __init__(self, wheel, price):
    super().__init__ (wheel, price)

bicycle = Bicycle(2, 100, "시마노")
bicycle.info()


마지막은 답 예측
다음 코드의 실행 결과를 예상해보세요.

class 부모:
  def 호출(self):
    print("부모호출")
class 자식(부모):
  def 호출(self):
    print("자식호출")= 자식().호출()

답 : 자식호출
이유 : 자식이기는 부모 없기 때문에
(오버라이딩은 덮어씌우는 거기 때문에 자식이 부모의 호출을 덮어씌워서 자식호출이 출력된다.)


profile
안녕하세요 게임개발을 공부하고 있는 돼지인간 입니다.

0개의 댓글