행위

"Python class"의 두 판 사이의 차이

DB CAFE

(인스턴스 메소드의 접근)
(인스턴스 메소드의 접근)
92번째 줄: 92번째 줄:
 
   'KR949'
 
   'KR949'
 
</source>   
 
</source>   
 
+
{{틀:타이틀 투명
파이썬 메서드의 '''첫번째 파라미터명'''은 관례적으로 '''self''' 라는 이름을 사용합니다.
+
|아이콘=filter_1
 
+
|제목=
 +
파이썬 메서드의 '''첫번째 파라미터명'''은 관례적으로 '''self''' 라는 이름을 사용.
 +
}}
 +
{{틀:타이틀 투명
 +
|아이콘=filter_2
 +
|제목=
 
호출 시 호출한 객체 자신이 전달되기 때문에 self라는 이름을 사용하게 된 것
 
호출 시 호출한 객체 자신이 전달되기 때문에 self라는 이름을 사용하게 된 것
 
+
}}
 +
{{틀:타이틀 투명
 +
|아이콘=filter_3
 +
|제목=
 
이를 이용하여 클래스에서 바로 메소드로 접근하면서 위에서 할당한 Flight의 객체 f를 파라미터로 전달함으로써 똑같은 결과값 얻습니다.
 
이를 이용하여 클래스에서 바로 메소드로 접근하면서 위에서 할당한 Flight의 객체 f를 파라미터로 전달함으로써 똑같은 결과값 얻습니다.
 +
}}
 +
{{틀:타이틀 투명
 +
|아이콘=filter_none
 +
|제목=
 +
* 클래스의 내부에 self 파라미터가 포함되는데 이를 이용한 접근법
 +
}}
  
#* 클래스의 내부에 self 파라미터가 포함되는데 이를 이용한 접근법
 
 
<source lang=python>     
 
<source lang=python>     
 
   >>> Flight.number(f) # f는 Flight객체
 
   >>> Flight.number(f) # f는 Flight객체

2020년 4월 1일 (수) 10:15 판

thumb_up 추천메뉴 바로가기


1 클래스 용어[편집]

  • 클래스(class) : 멤버와 메쏘드를 갖는 객체
  • 클래스 인스턴스(class instance)' : 클래스를 호출하여 만들어지는 객체
  • 멤버(member) : 클래스의 변수
  • 메소드(method) : 클래스의 함수
  • 어트리뷰트(attribute): 속성, 멤버 와 메쏘드의 전체
  • 슈퍼클래스(supperclass) : base class라고 하며 최상위 클래스
  • 서브클래스(subclass) : derived class라고 하며 수퍼클래스로터 상속된 하위 클래스
  • 인헤리턴스(inheritance) : 상속, A클레스를 수퍼클레스로 하는 클레스B는 B is-a A 관계라고 함
  • 멀티플 인헤리턴스(Multiple Inheritance) : 다중상속, 두개 이상의 클래스로 부터 상속 받음.
  • 폴리모피즘(Polymorphism) : 다형성, 상속관계내의 다른클래스의 인스턴스들이 같은 멤버 함수 호출에 대해 각각 다르게 반응하도록 하는 기능
  • 인캡술레이션(Encapsulation) : 은익,메쏘드와 멤버를 클래스 내에 포함시키고 외부에서 접근할수 있도록 인터페이스만을 공개하고 다른 속성은 숨기는 것
  • 컴포지션(Composition) : 합성, X라는 객체가 클래스A안에 포함되어 A의 각종 메소드를 구현하는데 사용됨. A가 x를 포함하므로 has-a 관계라 함.



2 파이썬 클래스 특징[편집]

notifications_active 특징
  • 클래스는 객체의 구조와 행동을 정의.
  • 객체의 클래스는 초기화를 통해 제어.
  • 메소드 오버로딩(같은이름,여러가지 파라메터)이 없다.
  • 접근제어자는 모두 Public(private,protected 존재 하지 않음)

3 클래스 정의[편집]

 attach_file

클래스를 작성하기 위해서는 class 키워드 사용하여 새로운 클래스 생성.

Python의 대부분 네이밍컨벤션이 단어와 단어사이에 _ 를 넣는다. 하지만 클래스의 네이밍컨벤션은 CamelCase 를 사용.

class CustomClass:
      def __init__(self, param):
          .......

3.1 클래스 생성 연습[편집]

에디터에서 airtravel.py 파일 생성.

클래스 생성은 아래와 같이 class 키워드 및 클래스의 이름을 입력하여 생성.

class Flight:
      pass

생성한 클래스는 REPL(read-eval-print loop,사용자의 입력 후 실행하고 결과를 반환시키는 프로그래밍 환경)에서 아래와 같이 import할 수 있음.

>>> from airtravel import Flight
  >>> Flight
  <class 'airtravel.Flight'>

3.2 클래스 객체 생성 및 변수에 할당[편집]

 attach_file

새로운 객체를 생성하기, java나 C# 등의 다른 언어와 다르게 new 키워드가 없다.

>>> f = Flight()
  >>> type(f)
  <class 'airtravel.Flight'>

4 클래스 메소드 작성[편집]

메소드란? 클래스 내의 함수

  • 메소드 작성하기
class Flight:
      def number(self):
          return 'KR949'

4.1 인스턴스 메소드의 접근[편집]

 attach_file

인스턴스 메소드란? 객체에서 호출되어질수 있는 함수

  • 인스턴스의 메소드 사용
>>> from airtravel import Flight
  >>> f = Flight()
  >>> f.number()
  'KR949'

 filter_1 파이썬 메서드의 첫번째 파라미터명은 관례적으로 self 라는 이름을 사용.

 filter_2 호출 시 호출한 객체 자신이 전달되기 때문에 self라는 이름을 사용하게 된 것

 filter_3 이를 이용하여 클래스에서 바로 메소드로 접근하면서 위에서 할당한 Flight의 객체 f를 파라미터로 전달함으로써 똑같은 결과값 얻습니다.

 filter_none

  • 클래스의 내부에 self 파라미터가 포함되는데 이를 이용한 접근법

>>> Flight.number(f) # f는 Flight객체
  'KR949'

5 생성자와 초기화자[편집]

    • 생성자(constructor)
 f = Flight() 

생성자로 객체생성을 호출받으면 먼저

  1. __new__ 를 호출하여 객체를 생성할당하고,
  2. __new__ 메소드가 __init__메소드를 호출

하여 객체에서 사용할 초기값들을 초기화하게됩니다.


간혹 여러 자료들을 보면.. __init__ 메소드를 생성자로 소개하는 경우가 있는데, 그렇지 않습니다.

자료 https://stackoverflow.com/questions/6578487/init-as-a-constructor

일반적으로 파이썬에서 클래스를 만들 시 __init__ 메소드만 오버라이딩하여 객체초기화에만 이용합니다.

5.1 생성자/초기화자 예제[편집]

5.1.1 생성자 / 초기화 실행 순서 확인[편집]

class Flight:
  	#초기화자 
	def __init__(self):
	  print('init')
	  super().__init__()

	# 생성자     
	def __new__(cls):
	  print('new')
	  return super().__new__(cls)

	# 메소드 
	def number(self):
	  return 'KR949'
  1. REPL에서 객체 생성
  2. __new__가 클래스 자체를 받으며 할당하게되고
  3. __init__가 self를 받으며 객체의 내부에서 사용할 속성을 초기화.
>>> from airtravel import Flight
  >>> f = Flight()
--- 결과 -- 
  new
  init

Flight클래스를 수정후 다시 실행 .

  1. __new__ 메소드는 자동으로 실행되므로 제거합니다.
  2. __init__ 메소드에 코드를 수정합니다.

아래의 코드에서 self._number 로 할당했는데 변수명의 _ 의 의미는 다음과 같습니다.

    • 내부적으로 사용되는 변수
    • 파이썬기본 키워드와 충돌을 피하기 위한 변수

_ 관련 네이밍컨벤션에 관련한 자료 https://spoqa.github.io/2012/08/03/about-python-coding-convention.html https://www.python.org/dev/peps/pep-0008/#naming-conventions

class Flight:
      def __init__(self, number):
          self._number = number
            
      def number(self):
          return self._number

다시 REPL에서 확인 합니다.

>>> from airtravel import Flight
   >>> f = Flight(5)
   >>> f.number()
   5
   >>> f._number
   5

6 접근제어자[편집]

Python은 기본적으로 다른언어에 있는 접근제어자(public, private, protected)가 없음. 기본적으로 모두 Public

6.1 초기화자(__init__)객체의 불변성을 확립(유효성검증 수행)[편집]

일반적으로 초기화자(__init__)에서 객체의 불변성을 확립하는 것이 좋습니다.

객체 생성시 들어올 값에 대해서 __init__에서 Validation을 수행합니다.

비행기 번호는 앞에 두글자는 영문이어야하며 대문자입니다.

그리고 뒤에 세번째 글자부터 마지막까지는 양의 정수여야합니다.

Flight클래스를 다음과 같이 변경해봅니다.

객체를 생성시 규칙에 맞지 않는 값이 들어오면 ValueError를 발생시킵니다.


class Flight:
    
      def __init__(self, number):
          if not number[:2].isalpha():
              raise ValueError("첫 두글자가 알파벳이 아닙니다.")
          if not number[:2].isupper():
              raise ValueError("첫 두글자가 대문자가 아닙니다.")
          if not number[2:].isdigit():
              raise ValueError("세번째 글자 이상이 양의 숫자가 아닙니다.")
          self._number = number
            
      ...생략
  >>> from airtravel import Flight
  >>> f= Flight("abc")
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/Users/Blidkaga/Documents/CodeLab/Python_Basic/airtravel.py", line 11, in __init__
      raise ValueError("첫 두글자가 대문자가 아닙니다.")
  ValueError: 첫 두글자가 대문자가 아닙니다.
  >>> f= Flight("AB0")
  >>> f= Flight("AB001")

7 비공개 속성[편집]

_ 언더바 한 개는 내부적으로만 사용되는 변수다라고 알지만, 사실 값을 얻어올수도 있고 할당도 가능합니다.

코딩컨벤션으로 파이썬을 쓰는 사람들이면 내부적인 변수구나 하고 알고 있을 뿐..

>>> f= Flight("AB001")
  >>> f._number
  'AB001'
  >>> f._number = 'abc'
  >>> f.number()
  'abc'
원천적인 접근을 막으려면 __ 더블 언더바(던더바)를 사용하면 막을 수 있습니다.

7.1 언더바를 던더바로 변경[편집]

_name 변수를 __name으로 변경하였습니다.

class Flight:
    
      def __init__(self, number):
          if not number[:2].isalpha():
              raise ValueError("첫 두글자가 알파벳이 아닙니다.")
          if not number[:2].isupper():
              raise ValueError("첫 두글자가 대문자가 아닙니다.")
          if not number[2:].isdigit():
              raise ValueError("세번째 글자 이상이 양의 숫자가 아닙니다.")
          self.__number = number
    
      def number(self):
          return self.__number

7.2 결과 확인.[편집]

number()인스턴스 메소드를 통해서 내부에서는 접근 가능한 모습을 보이나, 객체 f의 속성으로 접근 시 에러가 발생합니다.
>>> from airtravel import Flight
  >>> f= Flight("AB001")
  >>> f.number() 
  'AB001'
  >>> f.__number
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  AttributeError: 'Flight' object has no attribute '__number'

8 파이썬은 메소드 오버로딩이 없다.[편집]

메소드 오버로딩이란? : 하나의 클래스 내부에서 메소드 명칭은 똑같고, 인자를 다르게하는 형태를 허용합니다.

Java코드는 아래와 같은 코드를 허용합니다.

class Adder{  
      static int add(int a,int b)
      {
          return a+b;
      }  
      static int add(int a,int b,int c)
      {
          return a+b+c;
      }  
  }

파이썬은 메소드 오버로딩이 없습니다.

아래와 같은 코드가 있다면 첫번째 show는 무시되고, 두번째 show만 유지됩니다.

class Korea:
    
      def __init__(self, name,population, captial):
          self.name = name
          self.population = population
          self.capital = captial
    
      def show(self):
          print(
              """
              국가의 이름은 {} 입니다.
              국가의 인구는 {} 입니다.
              국가의 수도는 {} 입니다.
              """.format(self.name, self.population, self.capital)
          )
    
      def show(self, abc):
          print('abc :', abc)

결과

 >>> from inheritance import *
 >>> a = Korea('대한민국',50000000, '서울')
 >>> a.show()
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: show() missing 1 required positional argument: 'abc'


9 클래스 내부에서 메소드 호출[편집]

class MyClass:
	def set(self,v):
		self.value =v
	def incr(self):
		self.set(self.value+1)
	def put(self):
		print(self.value)

c = MyClass()
c.set('egg')
c.put()

10 생성자 와 소멸자[편집]

__init__ #생성자 __del__ #소멸자