IT/파이썬

[코딩도장] day23. 클래스 사용하기

_하늘여우_ 2020. 9. 16. 00:58

출처 : unsplash

■ 들어가기

- 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그


▶ Unit34. 클래스 사용하기

     - 34.1 클래스와 메서드 만들기

     - 34.2 속성 사용하기

     - 34.3 비공개 속성 사용하기

 

>> 34.1 클래스와 메서드 만들기 <<

- 클래스는 객체를 표현하기 위한 문법이다.
- 객체(object)?? 자동차, 나무, 집 등과 같이 특정한 개념이나 모양으로 존재하는 것
- 클래스(class)?? 프로그래밍으로 객체를 만들 때 사용하는 것
- 클래스의 정보를 다루는 것을 클래스의 "속성(attribute)"이라고 하며
- 클래스의 기능을 다루는 것을 "메서드(method)"라고 함
- 메서드는 클래스 안에 들어있는 함수를 의미

- 사용법
class 클래스이름 :
    def 메서드(self) :
        코드
- 클래스 이름은 대문자로 시작

>>> class Person :  # 클래스 생성
               def greeting(self) :  # 클래스 내 메서드 생성
                      print('Hello')

- 생성한 클래스를 사용하려면 인스턴스를 생성해야 함
- 사용법 : 인스턴스 = 클래스()

>>> james = Person()

 

1. 메서드 호출하기

- 메서드는 인스턴스를 통해 호출해야 함
- 사용법 : 인스턴스.메서드()

>>> james.greeting()  # 인스턴스 메서드 호출
Hello

 

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

- int, list, dict 등도 모두 클래스이고 파이썬 내 모든 자료형은 클래스

 

3. 인스턴스와 객체의 차이점?

- 인스턴스와 객체는 같은 것을 의미하며
- 객체만 지칭할 때는 그냥 객체(object)라고 부르며
- 클래스와 연관 지어 말할 때는 인스턴스(instance)라고 부름

>>> a = list(range(10))
>>> b = list(range(20))

- 리스트 변수 a, b 는 객체이고
- a, b는 list 클래스의 인스턴스이다.

 

[참고] 메서드 안에서 메서드 호출하기

- 메서드 안에서 메서드를 호출할 때는 self.메서드() 형식으로 호출해야 함
- self 없이 메서드 이름만 사용하면 클래스 바깥쪽에 있는 함수를 호출한다는 뜻

>>> def greeting() :
              print('AAA')
>>> class Person :
              def greeting(self) :
                     print('Hello')
              def hello1(self) :
                     self.greeting()  # self.메서드() 형식으로 클래스 안의 메서드를 호출
              def hello2(self) :
                     greeting()  # 클래스 밖의 메서드를 호출

>>> james = Person()
>>> james.hello1()  # 클래스 안의 메서드 호출
Hello
>>> james.hello2()  # 클래스 밖의 메서드 호출
AAA

 

[참고] 특정 클래스의 인스턴스인지 확인하기

- 현재 인스턴스가 특정 클래스의 인스턴스인지 확인 시 isinstance 함수 사용
- 맞으면 True, 아니면 False를 반환
- 사용법 : isinstance(인스턴스, 클래스)
- isinstance는 주로 객체의 자료형 판단 시 사용


>> 32.2 속성 사용하기 <<

- 사용법
class 클래스이름 :
    def __init__(self) :
        self.속성 = 값

소스 (class_attribute.py) 결과
class Person :
    def __init__(self) :
        self.hello = '안녕하세요.'

    def greeting(self) :
        print(self.hello)

james = Person()
james.greeting()
안녕하세요.

- 스페셜 메서드(spacial method) or 매직 메서드(magic method)??
  이름 앞뒤로 __(밑줄 두 개)가 붙은 메서드는 파이썬이 자동으로 호출하는 메서드
- james.greeting() 호출해서 클래스 내부 변수인 self.hello 값을 출력했음

- james.hello 를 통해 해당 값을 직접 호출 가능

>>> james.hello
'안녕하세요.'

 

1. self의 의미

- 인스턴스 자기 자신을 의미
- 인스턴스와 self 그림 추가

 

2. 인스턴스를 만들 때 값 받기

- __init__ 메서드에서 self 다음에 값을 받을 매개변수를 지정
- 매개변수를 self.속성에 넣어줌
- 사용법
class 클래스이름 :
    def __init__(self, 매개변수1, 매개변수2) :
        self.속성1 = 매개변수1
        self.속성2 = 매개변수2

소스 (class_init_attribute.py) 결과
class Person :
    def __init__(self, name, age, address) :    # 인스턴스 생성 시 이름, 나이, 주소를 받음
        self.hello = '안녕하세요.'
        self.name = name
        self.age = age
        self.address = address

    def greeting(self) :
        print('{0} 저는 {1}입니다.'.format(self.hello, self.name))

maria = Person('마리아', 20, '서울시 서초구 반포동')
maria.greeting()

print('이름: ', maria.name)
print('나이: ', maria.age)
print('주소: ', maria.address)
안녕하세요. 저는 마리아입니다.
이름:  마리아
나이:  20
주소:  서울시 서초구 반포동

- greeting메서드에서 해당 클래스 Person 내 name 속성에 접근하기 위해 self.name 으로 사용

- 만일 self. 없이 name만 사용하게 되면 클래스 바깥쪽의 동일 이름의 변수에 접근하게 됨 (없는 경우 NameError 발생)
- 즉, 클래스 안에서 속성에 접근할 때는 "self.속성" 형식으로 사용!
- 클래스로 인스턴스를 만들 때 값 받기 그림 추가

 

[참고] 클래스의 위치 인수, 키워드 인수

- 위치 인수, 리스트 언패킹 : *args 사용, 매개변수에서 값을 가져오려면 args[인덱스]로 사용

>>> class Person :
             def __init__(self, *args) :
                         self.name = args[0]
                         self.age = args[1]
                         self.address = args[2]

>>> maira = Person(*['마리아', 20, '서울시 서초구 반포동'])
>>> maria.name
'마리아'
>>> maria.age
20
>>> maria.address
'서울시 서초구 반포동'

- 키워드 인수, 딕셔너리 언패킹 : **kwargs 사용, 매개변수에서 값을 가져오려면 kwargs[키워드]로 사용

>>> class Person :
             def __init__(self, **kwargs) :
                        self.name = kwargs['name']
                        self.age = kwargs['age']
                        self.address = kwargs['address']

>>> maria1 = Person(name='마리아', age=20, address='서울시 서초구 반포동')
>>> maria2 = Person(**{'name':'마리아', 'age':20, 'address':'서울시 서초구 반포동'})
>>> maria1.name
'마리아'
>>> maria2.name
'마리아'

 

[참고] 인스턴스 생성한 뒤 속성 추가하기, 특정 속성만 허용하기

- 클래스의 인스턴스 속성은 __init__ 메서드에서 추가한 뒤 사용하는 방법 외에
- "인스턴스.속성 = 값" 의 형식으로 속성 추가 가능

>>> class Person :
             pass  # 빈 클래스 생성

>>> maria = Person() # 인스턴스 생성
>>> maria.name = '마리아'  # 인스턴스 생성 뒤 속성 name 추가
>>> maria.name
'마리아'

- 위의 방식은 해당 인스턴스에만 해당되며, 클래스로 다른 인스턴스 생성 시에는 추가된 속성 미적용

>>> james = Person() # 새로운 인스턴스 생성
>>> james.name
Traceback (most recent call last):
  File "<pyshell#134>", line 1, in <module>
    james.name
AttributeError: 'Person' object has no attribute 'name'

- 특정 속성만 허용하고 다른 속성은 제한하고 싶은 경우 __slots__ 사용

- __slots__에 미정의된 속성 호출 시 AttributeError 발생
- 사용법 : __slots__ = ['속성이름1', '속성이름2']

>>> class Person :
             __slots__ = ['name', 'age']


>>> maria = Person()
>>> maria.name = '마리아'
>>> maria.age = 20
>>> maria.address = '서울시 서초구 반포동'
Traceback (most recent call last):
  File "<pyshell#147>", line 1, in <module>
    maria.address = '서울시 서초구 반포동'
AttributeError: 'Person' object has no attribute 'address'

>> 34.3 비공개 속성 사용하기 <<

- 클래스의 속성은 메서드에서 self로 접근할 수 있으며, "인스턴스.속성" 형식으로 클래스 바깥에서 접근 가능
- 비공개 속성(private attribute)?? 클래스 바깥에서는 접근할 수 없고 클래스 안에서만 사용할 수 있는 속성
- 사용법
class 클래스이름 :
    def __init__(self, 매개변수) :
        self.__속성 = 값

소스 (class_private_attribute_error.py) 결과
class Person :
    def __init__(self, name, age, address, wallet) :
        self.name = name
        self.age = age
        self.address = address
        self.__wallet = wallet      # 변수 앞에 __를 붙여서 비공개 속성으로 생성

maria = Person('마리아', 20, '서울시 서초구 반포동', 10000)
maria.__wallet -= 10000             # 클래스 바깥에서 비공개 속성에 접근 시 에러 발생
Traceback (most recent call last):
  File "C:/project/class_private_attribute_error.py", line 9, in <module>
    maria.__wallet -= 10000             # 클래스 바깥에서 비공개 속성에 접근 시 에러 발생
AttributeError: 'Person' object has no attribute '__wallet'

- 비공개 속성은 클래스 안의 메서드에서만 접근 가능!

소스 (class_private_attribute.py) 결과
class Person :
    def __init__(self, name, age, address, wallet) :
        self.name = name
        self.age = age
        self.address = address
        self.__wallet = wallet      # 변수 앞에 __를 붙여서 비공개 속성으로 생성

    def pay(self, amount) :
        self.__wallet -= amount      # 비공개 속성은 클래스 안의 매서드에서만 접근 가능
        print('이제 {0}원 남았네요.'.format(self.__wallet))

# 인스턴스 생성
maria = Person('마리아', 20, '서울시 서초구 반포동', 10000)
maria.pay(3000)
이제 7000원 남았네요.

- 비공개 속성은 클래스 바깥으로 드러내고 싶지 않은 값에 사용
- 즉, 중요한 값인데 바깥에서 함부로 접근하거나 바꾸면 안 될 때 사용
- 비공개 속성을 변경하는 경우는 클래스의 메서드로만 한정

 

 

● 요약
1. 클래스는 특정 개념을 표현(정의)만 할 뿐 사용을 하려면 인스턴스로 만들어야 함
2. 속성, 메서드 사용 시 self와 인스턴스를 통해 사용해야 함
3. 속성 뿐만 아니라 메서드도 이름이 __(밑줄 두 개)로 시작하면 클래스 안에서만 호출가능한 비공개 메서드가 됨