ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 클래스(1)
    Python 2023. 10. 18. 14:51

    class

    클래스는 객체의 구조와 행동을 정의, 복잡한 문제를 다루기 쉽도록 만듦

    객체의 클래스는 초기화를 통해 제어

    클래스와 메서드 만들기

    class에 이름 지정하고 :(콜론) 붙인 뒤 다음 줄부터 def로 메서드 작성 > 반드시 들여쓰기

    보통 파이썬에서 클래스 이름은 대문자로 시작

    메서드의 첫 번째 매개변수는 반드시 self를 지정해야 함

    >>> class Person:
    ...     def greeting(self):
    ...         print('hello')
    ...
    >>> james = Person()    # Person 클래스로 james 인스턴스 만들기

    메서드 호출

    >>> james.greeting()    # 인스턴스를 통해 클래스의 메서드에 접근
    hello

    ↑ 인스턴스 메서드

     

    파이썬에서 흔히 볼 수 있는 클래스

    >>> a = int(10)             # a = 10과 같음
    >>> a
    10
    >>> b = list(range(10))
    >>> b
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>> c = dict(x=10, y=20)    # c = {'x':10, 'y':20}
    >>> c
    {'x': 10, 'y': 20}
    >>>
    >>>
    >>> maria = Person()
    >>>
    >>>
    >>> b = list(range(10))
    >>> b.append(20)
    >>> b
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20]
    >>>
    >>> 
    >>> # 자료형 확인
    >>> a = 10
    >>> type(a)
    <class 'int'>
    >>>
    >>> b = [0, 1, 2]
    >>> type(b)
    <class 'list'>
    >>>
    >>> c = {'x':10, 'y':20}
    >>> type(c)
    <class 'dict'>
    >>>
    >>> maria = Person()
    >>> type(maria)
    <class '__main__.Person'>

    빈 클래스 만들기

    class Person:
        pass

    메서드 안에서 메서드 호출

    >>> # self.메서드()
    >>>
    >>> class Person():
    ...     def greeting(self):
    ...         print('hello')
    ...     def hello(self):
    ...         self.greeting()
    ...
    >>> james = Person()
    >>> james.hello()
    hello

    특정 클래스의 인스턴스인지 확인

    >>> class Person:
    ...     pass
    ...
    >>> james = Person()
    >>> isinstance(james, Person)
    True
    >>>
    >>>
    >>> def factorial(n):
    ...     if not isinstance(n, int) or n < 0:    # n이 정수가 아니거나 음수이면 함수를 끝냄
    ...         return None
    ...     if n == 1:
    ...         return 1
    ...     return n * factorial(n-1)
    ...
    >>> factorial(5)
    120
    >>> factorial(-5)
    >>> factorial(5.0)
    >>>

     

    속성 사용
    # class의 선언
    # class 클래스이름:
    #     def __init__(self):
    #         self.속성 = 값
    
    class Person:
        def __init__(self):
            self.hello = '안녕하세요'
    
        def greeting(self):
            print(self.hello)
    
    james = Person()
    james.greeting()
    
    # 실행 결과
    안녕하세요

    __init__ 메서드는 james = Person()처럼 클래스에 ()괄호를 붙여 인스턴스를 만들 때 호출되는 특별한 메서드

    __init__(initialize) 이름 그대로 인스턴스(객체) 초기화

    앞뒤로 __ 밑줄 두 개가 붙은 메서드는 파이썬이 자동으로 호출해 주는 메서드 > 스페셜 메서드, 매직 메서드라고 부름

     

    self의 의미

    self는 인스턴스 자기 자신

    __init__의 매개변수 self에 들어가는 값은 Person() 그리고 self가 완성된 뒤 james에 할당

     

    인스턴스를 만들 때 값 받기

    # class 클래스이름:
    #     def __init__(self, 매개변수1, 매개변수2):
    #         self.속성1 = 매개변수1
    #         self.속성2 = 매개변수2
    
    class Person:
        def __init__(self, name, age, addr):
            self.hello = '안녕하세요'
            self.name = name
            self.age = age
            self.addr = addr
    
        def greeting(self):
            print('{} 저는 {}입니다.'.format(self.hello, self.name))
    
    maria = Person('마리아', 20, '수원시')
    maria.greeting()
    
    print('이름:', maria.name)
    print('나이:', maria.age)
    print('주소:', maria.addr)
    
    # 실행 결과
    안녕하세요 저는 마리아입니다.
    이름: 마리아
    나이: 20
    주소: 수원시

    클래스 안에서 속성에 접근할 때는 self.속성 형식, 클래스 바깥에서 속성에 접근할 때는 인스턴스.속성 형식으로 접근

     

    클래스의 위치 인수, 키워드 인수

    # 1. 위치 인수와 리스트 언패킹 *args
    class Person:
        def __init__(self, *args):
            self.hello = '안녕하세요'
            self.name = args [0]
            self.age = args [1]
            self.addr = args [2]
    
        def greeting(self):
            print(self.name, self.age, self.addr)
            
    # 리스트로 묶어서 호출
    maria = Person(*['마리아', 20, '수원시']) 
    maria.greeting()
    
    # 실행 결과
    마리아 20 수원시
    
    
    # 2. 키워드 인수와 딕셔너리 언패킹 **kwargs
    class Person:
        def __init__(self, **kwargs):
            self.hello = '안녕하세요'
            self.name = kwargs ['name']
            self.age = kwargs ['age']
            self.addr = kwargs ['addr']
        def greeting(self):
            print(self.name, self.age, self.addr)
    
    
    maria1 = Person(name='마리아', age=20, addr='수원시')
    maria2 = Person(**{'name':'마리아', 'age':21, 'addr':'서울시'})
    
    maria1.greeting()
    maria2.greeting()
    
    # 실행 결과
    마리아 20 수원시
    마리아 21 서울시

    인스턴스를 생성한 뒤에 속성 추가, 특정 속성만 허용

    # 인스턴스를 생성한 뒤 속성 추가
    class Person:
        pass
    
    maria = Person()
    maria.name = '마리아'
    print(maria.name)
    
    james = Person()
    print(james.name)
    
    # 실행 결과
    마리아
        print(james.name)
              ^^^^^^^^^^
    AttributeError: 'Person' object has no attribute 'name'

    마리아 인스턴스에만 name 속성을 추가했으므로 james 인스턴스에는 name 속성이 없음

    class Person:
        # __init__ 속성값이 없음
        def greeting(self):
            self.hello = '하이'
    
    maria = Person()
    # print(maria.hello)    # 아직 hello 속성이 없음
    maria.greeting()        # greeting 메서드를 호출해야
    print(maria.hello)      # hello 속성이 생성됨
    
    # 실행 결과
    하이

    인스턴스는 생성한 뒤에 속성을 추가할 수 있으므로 __init__ 메서드가 아닌 다른 메서드에서도 속성을 추가할 수 있음

    단, 이때는 메서드를 호출해야 속성이 생성됨

    # 특정 속성만 허용 __slots__
    class Person:
        __slots__ = ['name', 'age']
    
    
    maria = Person()
    maria.name = '마리아'
    maria.age = 20
    maria.addr = '수원시'
    
    # 실행 결과
        maria.addr = '수원시'
        ^^^^^^^^^^
    AttributeError: 'Person' object has no attribute 'addr'

    특정 속성만 허용하고 다른 속성은 제한하고 싶을 때 허용할 속성 이름만 slots에 리스트로 넣어 주면 됨

    반드시 문자열로 지정

     

    비공개 속성 사용
    # class 클래스이름:
    #     def __init__(self, 매개변수):
    #         self.__속성 = 값
    
    class Person:
        def __init__(self, name, age, addr, wallet):
            self.name = name
            self.age = age
            self.addr = addr
            self.__wallet = wallet    # 변수 앞에 __를 붙여 비공개 속성으로 만듦
    
    
    maria = Person('마리아', 20, '수원시', 10000)
    print(maria.name)
    print(maria.__wallet)    # 클래스 바깥에서 비공개 속성에 접근하면 에러 발생
    
    # 실행 결과
    마리아
        print(maria.__wallet)
              ^^^^^^^^^^^^^^
    AttributeError: 'Person' object has no attribute '__wallet'

    예제: 돈 내는 pay 메서드

    class Person:
        def __init__(self, name, age, addr, wallet):
            self.name = name
            self.age = age
            self.addr = addr
            self.__wallet = wallet    # 변수 앞에 __를 붙여 비공개 속성으로 만듦
        def pay(self, amount):
            self.__wallet -= amount   # 비공개 속성은 클래스 안의 메서드에서만 접근 가능
            print('이제 {0}원 남았습니다.'.format(self.__wallet))
    
    maria = Person('마리아', 20, '수원시', 10000)
    maria.pay(3000)
    
    # 실행 결과
    이제 7000원 남았습니다.
    
    # + 지갑에 든 돈이 얼마인지 확인하고 돈이 모자라면 쓰지 못하도록
    
        def pay(self, amount):
            if amount > self.__wallet:
                print('돈이 모자라네....')
                return
            self.__wallet -= amount
            print('이제 {0}원 남았습니다.'.format(self.__wallet))
            
    maria = Person('마리아', 20, '수원시', 10000)
    maria.pay(13000)
    
    # 실행 결과
    돈이 모자라네....

    비공개 메서드 사용

    class Person:
        def __greeting(self):
            print('hello')
    
        def hello(self):
            self.__greeting()
    
    james = Person()
    james.__greeting()    # 오류
    
    james.hello()
    
    # 실행 결과
        james.__greeting()
        ^^^^^^^^^^^^^^^^
    AttributeError: 'Person' object has no attribute '__greeting'

     

    연습 문제 예제
    # 34.5번 연습문제: 게임 캐릭터 클래스 만들기
    # 다음 소스 코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '베기'가 출력되게 만드세요.
    
    class Knight:
        def __init__(self, health, mana, armor):
            self.health = health
            self.mana = mana
            self.armor = armor
            
        def slash(self):
            print('베기')
            
    x = Knight(health=542.4, mana=210.3, armor=38)
    print(x.health, x.mana, x.armor)
    x.slash()
    
    
    # 실행 결과
    542.4 210.3 38
    베기
    
    # 34.6번 심사문제: 게임 캐릭터 클래스 만들기
    # 표준 입력으로 게임 캐릭터 능력치(체력, 마나, AP)가 입력됩니다
    # 다음 소스 코드에서 애니(Annie) 클래스를 작성하여 티버(tibbers) 스킬의 피해량이 출력되게 만드세요
    # 티버의 피해량은 AP * 0.65 + 400이며 AP(Ability Power, 주문력)는 마법 능력치를 뜻합니다
    
    class Annie:
        def __init__(self, health, mana, ability_power):
            self.health = health
            self.mana = mana
            self.ability_power = ability_power
            
        def tibbers(self):
            ap = self.ability_power * 0.65 + 400
            print('티버: 피해량 {}'.format(ap))
            
    health, mana, ability_power = map(float, input().split())
    
    x = Annie(health=health, mana=mana, ability_power=ability_power)
    x.tibbers()
    
    
    # 실행 결과
    
    511.68 334.0 298      # 표준 입력
    티버: 피해량 593.7    # 표준 출력
    
    1803.68 1184.0 645     # 표준 입력
    티버: 피해량 819.25    # 표준 출력

    'Python' 카테고리의 다른 글

    클래스(3)  (0) 2023.10.23
    클래스(2)  (0) 2023.10.18
    클로저  (0) 2023.10.17
    람다  (0) 2023.10.17
    재귀호출  (0) 2023.10.17
Designed by Tistory.