Object-Oriented Programming

Python Object-Oriented Programming

만들어 놓은 코드를 재사용 하고싶다

생각해보기

  • 주체들을 만들고 주체들의 행동들 데이터의 구조를 나누어서 코딩

개요

객체 : 속성과 행동을 가지는 일종의 물건

속성은 변수로, 행동은 함수로 표현

oop는 설계도 (틀)에 해당되는 Class와 실제 구현체인 Instance로 나뉨

Class 구현

알아두면 좋은 Python naming rule

  • 파이썬의 함수와 변수명에서는 _로 띄어쓰기를 구분하는 snake case 를 사용
  • 파이썬의 Class 명에는 띄어쓰기 부분에 대문자를 사용하는 camel case 를 사용

Attribute 추가하기

  • Attribute 추가는 __ init __과 함께
  • init은 객체 초기화 함수

파이썬에서 __는 특수한 예약함수나 변수, 함수명 변경(맹글링)으로 사용

ex) __ main __ , __ str __ , __ init __

Method 구현하기

  • 반드시 self를 추가해야지만 class 함수로 인정이 됨
  • self : Instance 자신을 의미함
  • 인스턴스 생성시 그 인스턴스 내부에서는 self로 불림

ex)

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 SoccerPlayer(object):
def __init__(self, name, position, back_number):
self.name = name
self.position = position
self.back_number = back_number
def __str__(self):
return "Hello, My name is %s. I play in %s in center " % \
(self.name, self.position)

def __add__(self, other):
return self.name + other.name

def change_backnumber(self, new_number):
print("선수의 등번호를 변경합니다 From : %d To : %d" %(self.back_number,new_number))

a = SoccerPlayer('son','FW',7)
b = SoccerPlayer('kain','FW',14)
print(a)
print(a+b)
a.change_backnumber(9)

# Hello, My name is son. I play in FW in center
# sonkain
# 선수의 등번호를 변경합니다 From : 7 To : 9

상속(Inheritance)

  • 부모 클래스로 부터 속성과 Method를 물려받은 자식 클래스를 생성 하는 것
  • 다른 클래스의 object에 부모클래스의 이름을 넣어주면 상속이됨
  • super() : 그것의 부모클래스를 그대로 받아와 부모객체를 사용할때 사용
  • super().about_me() : 부모클래스의 method 사용

Polymorphism

  • 같은 이름의 method의 내부 로직을 다르게 작성
  • Dynamic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
def talk(self):
return 'Meow!'

class Dog(Animal):
def talk(self):
return 'Woof! Woof!'

animals = [Cat('Missy'),
Cat('Mr. Mistoffelees'),
Dog('Lassie')]
for animal in animals:
print(animal.name + ': ' + animal.talk())

#굳이 cat과 dog의 함수이름을 다르게 할 필요없이 내용만 다르게 함

가시성

  • 객체의 정보를 볼 수 있는 레벨을 조정하는 것
  • 누구나 객체 안의 모든 변수를 볼 필요가 없음

@ 캡슐화

클래스를 설계시 정보은닉, 클래스간 간섭/공유 최소화

  • Product 객체를 Inventory 객체에 추가

  • Inventory에는 오직 Product 객체만 들어감

  • Inventory에 Product가 몇 개인지 확인이 필요

  • Inventory에 Product items 접근 허용

private 변수로 선언하는법 : self.__items = []

private 변수로 선언시 외부에서 접근이 불가능함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Product(object):
pass
class Inventory(object):
def __init__(self):
self.__items = []
def add_new_item(self, product):
if type(product) == Product:
self.__items.append(product)
print("new item added")
else:
raise ValueError("Invalid Item")
def get_number_of_items(self):
return len(self.__items)

my_inventory = Inventory()
my_inventory.add_new_item(Product())
print(my_inventory.__items)
#접근이 안되고 에러가 뜬다
#만약 써야된다면?

만약 외부에서 Private 변수를 써야하는 상황이 존재한다면? -> property decorator를 사용

내부에서 접근해서 반환해주는 기능을 해줌

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 Product(object):
pass
class Inventory(object):
def __init__(self):
self.__items = []
def add_new_item(self, product):
if type(product) == Product:
self.__items.append(product)
print("new item added")
else:
raise ValueError("Invalid Item")
def get_number_of_items(self):
return len(self.__items)
@property
def items(self):
# 보통 아래처럼 외부에서 수정이 가능하게 반환하지 않고 copy본을 return해줌
return self.__items


my_inventory = Inventory()
my_inventory.add_new_item(Product())
print(my_inventory.items)
#이럼 접근이 됨
#decorator은 함수명을 변수명처럼 쓸수있게 해주는!!

Decorate

이해하기 위한 개념들

  • First-class objects
  • Inner function
  • decorator

First-Class objects

일등 함수, 일급 객체

변수나 데이터 구조에 할당이 가능한 객체

파이썬의 모든 함수는 1급함수이다

파이썬의 모든함수는 파라메터로 전달가능

1
2
3
4
5
6
7
8
def square(x):
return x*x
f = square
f(5)
#이건 매우 특이하고 평소에 생각하지 않았던 것이다

def formula(method, arg_list):
return([method(value) for value in arg_list])

이렇게 함수도 변수처럼 지정해서 사용할수도 있고 함수의 파라메터로 넣을수도 있구만 :scream:

Inner Function

  • 함수내에 또다른 함수의 존재
1
2
3
4
5
6
7
8
9
10
11
12
def print_msg(msg):
def printer():
print(msg)
printer()


#closure
def print_msg(msg):
def printer():
print(msg)
return printer

매우 흔한 구조임

Closure : inner function을 return 값으로 반환

1
2
3
4
5
6
7
8
9
10
11
def star(func):
def inner(*args, **kwargs):
print("*" * 30)
func(*args, **kwargs)
print("*" * 30)
return inner

@star
def printer(msg):
print(msg)
printer("Hello")

Decorator

Module and Project

  • 파이썬은 대부분의 라이브러리가 이미 다른사용자가 다 구현해 놓음
  • 이걸 불러와서 쓰는게 굉장히 큰 장점

남이 만든 프로그램 쓰는 법 객체 < 모듈

Module

Overview

  • 어떤 대상의 부분 혹은 조각

    ex)레고 블록 같은것들

  • 프로그램을 나눈 작은 프로그램 조각들

  • Package : module의 모음

  • 파이썬에서의 module == py파일

  • import ~~~ 해주면 됨

  • 그럼 그안에 있는 모든 코드가 메모리 로딩이 일어남

  • 같은 directory안에있어야됨

  • 코드를 쉽게 로딩할수 있게 pycache라는 폴더가 생김

name space

  • 모듈호출시 범위를 지정하는 방법
  • 모듈안에는 함수와 클래스등이 존재가능
  • 일부만 호출해주기 위해 From 과 import를 씀
  • 모듈에서 특정함수나 클래스를 호출하기
  • 되도록이면 특정 함수가 어디서 왔는지를 보여주기 위해 모듈명을 별칭으로 쓰는 방법을 쓰자 라고 생각

Package

  • 다양한 모듈들의 합
  • 다양한 오픈소스들이 패키지로 관리됨

폴더별로 __init.py 구성하기

  • 현재 폴더가 패키지임을 알려주는 초기화 파일

  • 없으면 package가 아님

  • 하위촐더와 py파일을 모두포함함

  • import 와 all keyword사용

참고 : package namespace

package내에서 다른폴더에있는 모듈을 부를떄 상대 참조로 호출

from ..sound.echo [.. 점이 2개 : 부모디렉토리기준]

from game.graphic.render -> 이건 절대참조

from . render -> 현재 디렉토리 기준

오늘 배웠던게 정말 중요했던것 같다. 다른 문법들보다 이 package의 구성같은게 평소에 굉장히 모호했는데 이번에 확실하게 잡고 넘어 가야지.

Author

jo-member

Posted on

2021-01-21

Updated on

2021-07-12

Licensed under

Comments