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


  • 일반적인 클래스 정의

class Employee:
    pass # do nothing

emp_1 = Employee()
emp_2 = Employee() # emp_1, emp2는 클래스(Employee)의 인스턴스, 주소 다름

 

  • 인스턴스 변수 설정

emp_1.first = "kildong"
emp_1.last = "hong"
emp_1.email = "kildong.hong@gmail.com"
emp_1.pay = 100


  • 설정 값 확인

print('{} / {}'.format(emp_1.email, emp_1.first))



Class Variables  클래스 변수


  • 클래스 전역 변수

- cls 지시자를 통해 access 가능


  • 인스턴스 변수는 self 지시자를 통해 access


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 를 통해 호출하는 것이 바람직


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

  •  부모 클래스의 속성/메소드와 같은 속성/메소드를 자식 클래스에서 재정의 가능


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 여부 확인

print(isinstance(mgr_1, Manager))        #True
print(issubclass(Developer, Employee))    #True
print(issubclass(Employee, Manager))      #False



다중상속

  • python은 다중상속을 지원하므로 instance 키워드가 없음
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()




+ Recent posts