Python 이란?
- 1990년 암스테르담의 귀도 반 로섬(Guido Van Rossum)이 개발한 인터프리터(Interpreter) 언어
- 고대 신화에 나오는 파르나소스 산의 동굴에 살던 큰 뱀 (파이썬 표지와 아이콘이 뱀 모양)
- 다양한 라이브러리들과 통합환경의 동시 제공 (numpy, pandas 등)
- 관련 서비스
- 파일 동기화 서비스 드롭박스(Dropbox)
- Web 개발 프레임워크 장고(Django/Flask)
- 머신러닝/딥러닝 라이브러리(Sklearn, tensorflow, mxnet, pytorch..)
Python 특징
Interpreter 기반의 객체 지향 언어
- 바이트 코드 컴파일을 지원하는 동적 인터프리팅 언어 (.py > .pyc)
- python shell 에서 interpreter 모드 테스트 가능
플랫폼 독립적 언어
- Windows, MAC OS, Palm OS, Android, Unix 계열, Linux 계열 등 다양한 OS 지원
유연한 확장
- 컴파일된 외부 모듈을 인터프리터 내부로 동적로딩 지원
동적 타이핑
- 컴파일 시점이 아닌 프로그램 실행 시점에 Type Checking 을 수행
- 개발생산성 향상 가능
- 디버그 속도 저하 발생 가능
리플렉션 (Reflection)
- Runtime 시 객체에 대한 상세 정보 획득 가능
- Object Properties 조작 가능
쉬운 문법, 빠른 속도
- 프로그램의 뼈대는 파이썬으로 짜고 빠른 실행속도를 필요로 하는 부분은 C 로 구현하여 import 가능
- Python 의 많은 라이브러리가 C 로 구현됨
간결함
- { } (브레이스) 없이 들여쓰기를 통해 단락 구분
- 강제적인 인덴테이션으로 가독성 향상
OOP - Classes and Instances
일반적인 클래스 정의
1 2 3 4 5 | class Employee: pass # do nothing emp_1 = Employee() emp_2 = Employee() # emp_1, emp2는 클래스(Employee)의 인스턴스, 주소 다름 |
인스턴스 변수 설정
1 2 3 4 | emp_1.first = "kildong" emp_1.last = "hong" emp_1.email = "kildong.hong@gmail.com" emp_1.pay = 100 |
설정 값 확인
1 | print ( '{} / {}' . format (emp_1.email, emp_1.first)) |
Class Variables 클래스 변수
클래스 전역 변수
- cls 지시자를 통해 access 가능
인스턴스 변수는 self 지시자를 통해 access
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class Employee: raise_amount = 1.04 def __init__( self , first, last, pay): self .first = first self .last = last self .pay = pay self .email = first + '.' + last + '@email.com' emp_1 = Employee( 'killdong' , 'hong' , 10000 ) emp_2 = Employee( 'chunhang' , 'sung' , 2000 ) # raise_amount - 클래스 변수 # first, last, pay, email - 인스턴스 변수 / / 클래스 변수 값을 변경하면 해당 인스턴스의 값이 전부 변경된다. Employee.raise_amount = 1.05 print (emp_1.raise_amount) # 1.05 print (emp_2.raise_amount) # 1.05 print (Employee.raise_amount) # 1.05 / / 인스턴스 변수에 대한 값을 변경하면 클래스 변수의 raise_amount 는 바뀌지 않는다. emp_1.raise_amount = 1.06 print (emp_1.raise_amount) # 1.06 print (emp_2.raise_amount) # 1.05 print (Employee.raise_amount) # 1.05 |
Static Method and Class Method
Instance Method
- 일반적인 메소드 형태
- parameter 는 self 부터 시작 (instance 의미)
Class Method
- @classmethod annotation 으로 접근가능
- parameter 는 cls 부터 시작 (class 의미)
Static Method
- @staticmethod annotation 으로 접근가능
- method parameter 에 self, cls 없음
- util 성 메소드 작성에 적합
- class, instance를 통해서 접근 가능하나 되도록 class 를 통해 호출하는 것이 바람직
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | class Employee: raise_amount = 1.04 num_of_emps = 0 ### instance개수를 담을 class variables def __init__( self , first, last, pay): self .first = first self .last = last self .pay = pay self .email = first + '.' + last + '@email.com' Employee.num_of_emps + = 1 ## instance개수를 +1씩 증가시킨다. def fullname( self ): return '{} {}' . format ( self .first, self .last) def apply_raise( self ): self .pay = int ( self .pay * self .raise_amount) #Instance Variables는 'self.변수명'으로 접근 가능 # class method선언은 @classmethod annotation을 사용하고 # 메소드 파라미터의 첫인자는 cls를 기본적으로 설정한다. @classmethod def set_raise_amt( cls , amount): cls .raise_amount = amount @classmethod def from_string( cls , emp_str): first, last, pay = emp_str.split( '-' ) #return Employee(first, last, pay) # __init__ parameter와 같은 순서로 객체를 생성하라. return cls (first, last, pay) #static method는 별도의 parameter를 전달하지 않는다. # weekday()는 '0:월, 1:화, 2:수, 3:목, 4:금, 5:토, 6:일'의 값을 리턴 @staticmethod def is_workday(day): if day.weekday() = = 5 or day.weekday() = = 6 : return False return True # class method를 통해서 class variables를 변경한다. Employee.set_raise_amt( 1.05 ) # class method를 통한 instance 생성 new_emp_1 = Employee.from_string(emp_str_1) new_emp_2 = Employee.from_string(emp_str_2) #static method 호출 > class를 통해 접근 import datetime my_date = datetime.date( 2016 , 7 , 11 ) print (Employee.is_workday(my_date)) # instance를 통해서도 호출은 가능하나, class를 통해서 호출하는 것이 바람직. new_emp_1.is_workday(datetime.date( 2018 , 6 , 2 )) |
Inheritance-Subclasses
- 부모 클래스의 속성/메소드와 같은 속성/메소드를 자식 클래스에서 재정의 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | class Employee: raise_amount = 1.04 def __init__( self , first, last, pay): self .first = first self .last = last self .pay = pay self .email = first + '.' + last + '@email.com' def fullname( self ): return '{} {}' . format ( self .first, self .last) def apply_raise( self ): self .pay = int ( self .pay * self .raise_amount) #Instance Variables는 'self.변수명'으로 접근 가능 #Employee를 상속하는 자식클래스를 선언 class Developer(Employee): raise_amount = 1.10 def __init__( self , first, last, pay, prog_lang): #부모 클래스의 메소드를 실행한다. super ().__init__(first, last, pay) #Employee.__init__(first, last, pay) #이 코드도 상위 클래스 __init__ call self .prog_lang = prog_lang dev_1 = Developer( 'kildong' , 'hong' , 10000000 ) # Java와 달리 new keyword를 사용하지 않음. dev_2 = Developer( 'sunghun' , 'kim' , 5000000 ) # emp_1(객체)는 클래스(Employee)의 인스턴스(Instance)이다. #자식클래스가 부모 클래스의 속성과 메소드를 상속하여 정상 동작함. print (dev_1.email) print (dev_2.email) # Employee 를 상속하는 Manager 클래스 class Manager(Employee): #parameter=None은 해당 parameter가 값이 없을 경우 None으로 설정한다.(default value) def __init__( self , first, last, pay, employees = None ): #부모 클래스의 메소드를 실행한다. super ().__init__(first, last, pay) if employees is None : self .employees = [] else : self .employees = employees #부모 클래스에 없는 메소드 정의 가능 def add_emp( self , emp): if emp not in self .employees: self .employees.append(emp) #list append def remove_emp( self , emp): if emp in self .employees: self .employees.remove(emp) #list remove def print_emps( self ): for emp in self .employees: print ( '-->{}' . format (emp.fullname())) |
Instance Type / Subclass 여부 확인
1 2 3 | print ( isinstance (mgr_1, Manager)) #True print ( issubclass (Developer, Employee)) #True print ( issubclass (Employee, Manager)) #False |
다중상속
- python은 다중상속을 지원하므로 instance 키워드가 없음
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class parentA: def print ( self ): print ( 'parentA' ) def printA( self ): print ( 'parentA print' ) class parentB: def print ( self ): print ( 'parentB' ) def printB( self ): print ( 'parentB print' ) class Child(parentA, parentB): def print ( self ): super (). print () print ( 'child C' ) ins = Child() ins. print () # 다중 상속 클래스의 선언된 순서에서 우선한 것의 메소드를 실행한다. ins.printB() ins.printA() |