Home 파이썬 기초4
Post
Cancel

파이썬 기초4

객체지향 프로그래밍(OOP)

  • 객체 : 속성(Attribute)와 행동(Action)을 가지는 실생활에서의 물건
  • OOP는 이러한 객체 개념을 사용해 프로그래밍
  • 속성은 변수, 행동은 함수로 표현된다.

class

  • class 선언 class class_name(object): object는 자동 상속받아 Python3부터는 작성하지 않아도 된다.
  • 속성(Attribute) 추가 __init__(self, a1, a2 ..): 객체 초기화 함수를 작성해 멤버 변수들을 선언 및 초기화 한다.

    1
    2
    3
    4
    
      class TestClass():
      	def __init__(self, name : str, age : int) :
      		self.name = name
      		self.age = age
    
  • 객체 생성

    class라는 설계도를 이용해 각각의 상태를 가지고 있는 객체를 생성할 수 있다.

    1
    2
    3
    
      my = TestClass("kms", 28)
      my.age # 28
      my.name # kms
    

    my = TestClass("kms", 28)은 TestClass()클래스의 init 함수를 호출해 self에 my, name에는 “kms”, age에는 28이 parameter로 전달된다.

  • [참고]Python naming rule

    snake_case : 띄어쓰기 부분에 underscore(_)를 추가하여 뱀 처럼 늘여쓰기 함수,변수명에 사용

    CamelCase: 띄어쓰기 부분에 대문자, Class명에 사용

  • [참고]Python __의미

    __는 특수한 예약 함수나 변수 그리고 함수명 변경(맨글링)으로 사용된다.

    ex). __str__(self): 는 이 객체를 print함수로 출력하려고할때 __str__함수의 반환값을 출력하게 된다..


상속(Inheritance)

부모클래스로 부터 속성과 Method를 물려받는 자식 클래스를 생성하는것

1
2
3
4
5
6
7
8
9
class TestInheritance(TestClass): # TestClass를 상속받는 자식 클래스 선언
	def __init__(self, name, age, gender):
		super().__init__(name,age)
		self.gender = gender

my1 = TestInheritance("kms",28, "man")
my.age # 28
my.name # kms
my.gender # man

자식class는 super 키워드를 사용해 부모class의 함수 또는 변수를 사용할 수 있다.


다형성(Polymorphism)

같은 이름의 함수를 동작이 다르게 작성할 수 있다. Dynamic Typing 특성으로 파이썬에서는 같은 부모 클래스의 상속에서 주로 발생한다.


가시성(Visbility) 캡슐화

__를 사용해 변수를 private으로 지정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
class TestClass():
	def __init__(self, name : str, age : int) :
		self.__name = name
		self.__age = age

	@property
	def name(self):
		return self.__name

	@property
	def age(self):
		return self.__age

property 데코레이터를 활용해서 getter, setter를 만들 수 있다. 위의 코드에서는 name, age라는 getter들을 만들었고 호출할 때 변수처럼 사용이 가능하다. my.name

list같은 mutable을 반환하는 getter은 외부에서 변경할 수 있기때문에 deepcopy해서 반환해주는게 일반적이다.


Decorate

함수를 한번 감싸주어 실행 전과 후의 동작을 작성할 수 있고, 같은 식의 반복되는 함수를 래핑하여 다른 동작을 하도록 작성할 수 있게 해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def star(func):
	def inner(s):
		print("*" * 30) # 전처리
		func(s)
		print("*" * 30) # 후처리
	return inner

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

printer("Hello")

## output
# ******************************
# Hello
# ******************************

@star아래 printer함수가 작성되어있다. printer함수를 호출하게되면 star의 parameter로 printer함수가 들어가게되고, inner의 parameter s로는 printer를 호출했을 때 작성한 Hello가 들어간다.

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
def star(func):
	def inner(s):
		print("*" * 30) # 전처리
		func(s)
		print("*" * 30) # 후처리
	return inner

def charA(func):
	def inner(s):
		print("A" * 30) # 전처리
		func(s)
		print("A" * 30) # 후처리
	return inner

@star
@charA
def printer(msg):
	print(msg)

printer("Hello")

## output
# ******************************
# AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Hello
# AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# ******************************

위와같이 두번 중첩 된 경우 printer함수가 charA함수의 parameter로 들어가고, charA함수가 star함수의 parameter로 들어가게된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
def gen_power(exp):
	def wrapper(f):
		def inner(*args):
			result = f(*args)       # result = raise_two(7) # 7 ^ 2
			return exp**result      # 2^49
		return inner
	return wrapper

@gen_power(2)
def raise_two(n):
	return n**2

raise_two(7) # 562949953421312

@gen_power(2)로 2가 exp에 들어가게 되고 wrapper함수의 parameter로 raise_two함수가 들어가게 된다. inner 함수의 parameter로는 raise_two의 n이 들어가게된다.

  • First class objects

    변수나 데이터 구조에 할당이 가능한 객체, parameter로 전달이 가능하거나 리턴값으로 사용 가능한 함수를 First class ojbects라고 한다

  • inner function

    함수 내부에 또 다른 함수가 있는것

    1
    2
    3
    4
    5
    6
    7
    
      def print_msg(msg):
      	def printer():
      		print(msg)
      	return printer
    
      another = print_msg("Hello")
      another()
    
  • Nested function & Closure function

    https://smartkuma.tistory.com/entry/Python-nested-function-closure-decorator-정리


모듈과 패키지

작은 단위의 모듈들을 모아놓은 단위를 패키지라고 한다.


모듈

  • 모듈 사용하기

    import를 사용해 다른 py파일에 있는 함수 클래스 등을 사용할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
      ### my_module.py ###
      def print_hello():
      	print("Hello")
    
      def print_boo():
      	print("boo")
    
      if __name__ == "__main__":
      	print("bbbbbbb")
    
      ### test.py ###
      import my_module
    
      my_module.print_hello()
      my_moduel.print_boo()
    

    main일때의 동작을 명시적으로 작성하지않으면 import되는 순간 모든 코드가 수행되어 원하지 않는 결과를 얻을 수 있다.

  • namespace
    1. Alias 설정

      모듈의 별칭을 지정해 사용하는 것이다.

      1
      2
      3
      
       import my_module as m
       m.print_hello()
       m.print_boo()
      
    2. 모듈에서 특정 함수 또는 클래스만 호출

      1
      2
      
       from my_module import print_hello
       print_hello()
      
    3. 모듈에서 모든 함수 모든 클래스 호출

      1
      2
      3
      
       from my_module import *
       print_hello()
       print_boo()
      
  • pycache

    메모리 로딩 속도를 높이기 위해 미리 컴파일? 시켜놓는것..


패키지

하나의 대형 프로젝트를 만드는 코드의 묶음으로 다양한 모듈들의 집합이다.

다른 디렉토리에 있는 모듈을 import할 수 있다.

  • init.py

    현재 폴더가 패키지임을 알리는 초기화 스크립트로 각 디렉토리별로 이 파일이 있어야 패키지로 인식된다(3.3 이전)

    __all__키워드를 사용해 현재 디렉토리에 있는 init파일이 import할 디렉토리 혹은 모듈 리스트를 작성하고, 이 리스트들을 import해준다.

  • main.py

    프로젝트 root디렉토리에 있는 파일이며 해당 프로젝트 디렉토리를 python으로 실행시켰을 때 이 파일이 실행된다.

가상환경 구성

각 프로젝트마다 사용해야하는 파이썬 혹은 라이브러리들의 버전이 다를 수 있고 혹시 충돌이 발생할 경우 해당 가상환경을 지우고 다시 설정하면되기 때문에 가상환경을 사용한다.


가상환경 설정(conda)

conda create -n env_name python=version와 같은 형식으로 사용한다.

conda create -n my_project python=3.8 python3.8을 사용하는 my_project라는 가상 환경만들었다.

conda activate my_project 로 해당 가상 환경을 사용할 수 있고,

conda deactivate 로 해당 가상 환경에서 나올 수 있다.


패키지 설치

conda install <패키지 이름>

내가 설치할 패키지 : tqdm, matplotlib

  • matplotlib

    대표적인 파이썬 그래프 관리 패키지, 그래프를 화면에 출력해줌

  • tqdm

    loop의 남은 시간을 측정해준다.


Numpy

numpy는 Numerical python의 약자로 다차원 연산을 위한 많은 도구를 제공해주는 라이브러리이다.


List로 배열 만들기

numpy의 array함수에 list를 넣어주면 ndarray객체로 변환해준다.

1
2
3
4
5
6
import numpy as np # np라는 이름으로 import하는것이 관례

a = np.array([1,2,3])
b = np.array([2,4,8])

type(a) # numpy.ndarray

numpy의 배열은 같은 자료형을 가지는 배열이다. (다른 자료형으로 array를 만들어도 잘 만들어지지만 연산 할 때 에러가 발생한다.) 다차원 배열은 리스트를 중첩해서 생성할 수 있다.

1
2
3
import numpy as np

c = np.array([[1,2,3],[2,4,8]])

rank, shape

numpy에서 rank는 배열이 몇 차원을 나타내며 shape는 각 차원의 크기담고 있는 튜플을 반환한다. c.shape # (2,3) shape의 결과로 나온 튜플을 보면 2차원이며 1차원의 크기는 2, 2차원 배열의 크기는 3인것을 알 수 있다. rank(차원은) ndim으로 알 수 있다.


numpy 함수를 사용해 배열만들기

list를 사용하지않고 numpy의 함수를 사용해 배열을 생성할 수 있다.

  1. zeros((n,m,..))

    n *m *.. 크기의 0으로 채워진 배열을 만든다.

    1
    2
    3
    4
    5
    6
    7
    
     import numpy as np
    
     a = np.zeros((2,3))
     print(a)
     ## output
     #  [[0. 0. 0.]
     #  [0. 0. 0.]]
    
  2. ones((n,m,..))

    n * m *.. 크기의 1로 채워진 배열을 만든다.

    1
    2
    3
    4
    5
    
     a = np.ones((2,3))
     print(a)
     ## output
     #  [[1. 1. 1.]
     #  [1. 1. 1.]]
    
  3. full((n,m,..), num)

    n * m * .. 크기의 num으로 채워진 배열을 만든다.

    1
    2
    3
    4
    5
    
     a = np.full((2,3),100)
     print(a)
     ## output
     #  [[100 100 100]
     #  [100 100 100]]
    
  4. eye(n)

    n * n 크기의 단위행렬을 만든다.

    1
    2
    3
    4
    5
    6
    
     a = np.eye(3)
     print(a)
     ## output
     #  [[1. 0. 0.]
     #   [0. 1. 0.]
     #   [0. 0. 1.]]
    
  5. random.random((n,m,..))

    n * m *.. 크기의 random으로 채워진 배열을 만든다.

    1
    2
    3
    4
    5
    
     a = np.random.random((2,3))
     print(a)
     ## output
     #  [[0.56836423 0.27221542 0.24358307]
     #   [0.49611743 0.69032221 0.64952519]]
    

배열 인덱싱

a[i][j]와 같이 C, C++처럼 배열을 사용할 수 있고, a[i, j]와 같이 사용도 가능하다.

1
2
3
4
5
6
a = np.array([[2,3,4],[4,5,6]])
print(a[1][1])
print(a[1,1])
## output
#  5
#  5

자료형

numpy의 자료형과 pyhton기본 자료형의 차이는 세부 비트이다. 세부 비트는 자료형의 비트 크기를 나타낸다.

  • int8, int16, int32, int64
  • uint8, uint16, uint32, uint64
  • float16, float32, float64, float128
  • complex64, complex128, complex256
  • bool
  • string
  • object
  • unicode

배열의 data type을 알기 위해서는 dtype를 사용하면 된다.

1
2
3
4
5
6
7
8
9
a = np.array(([2,3,4],[4,5,6]], dtype=np.float32)
print(a.dtype)
## output
#  float32

b = np.ones((2,2), np.int64)
print(b.dtype)
## output
#  int64

dtype는 생략해도되고 ones의경우 기본 float32로 배열이 생성되는데 int타입을 지정하면 int타입으로 배열이 생성된다. python의 경우 숫자 자료형의 최대 최소가 정해져있지 않지만 numpy가 c로 만들어져있어 자료형의 크기가 있어야 한다고한다.


reshape

reshape함수는 배열의 차원을 변경하는경우 사용하는 함수이다.

reshape(배열, shape), reshape(shape)처럼 사용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np

a_list = [1,2,3,4,5,6]
a = np.reshape(a_list,(2,3))
print(a)
## output
#  [[1 2 3]
#   [4 5 6]]

b = np.reshape(a,(3,2))
print(b)
## output
#  [[1 2]
#   [3 4]
#   [5 6]]

c = a.reshape(1,2,3)  ## b와 다르게 ndarry a의 reshape를 호출
print(c)
## output
#  [[[1 2 3]
#   [4 5 6]]]

c의 경우 shape를 2,3에서 1,2,3으로 바꾸어 가장 밖에 대괄호가 하나 추가된것을 볼 수 있다.

reshape의 경우 해당 바꾸려는 shape로 변경할 수 없는경우 (예를들어 list에 3개가 들어있는데 (2,2)로 만든다던지..) Error가 발생한다.

This post is licensed under CC BY 4.0 by the author.