본문 바로가기
IT/Data Analysis

파이썬 속성 강좌: 심화

by Cyber_ 2024. 8. 11.

1. 객체 지향 프로그래밍

다른 프로그래밍 언어와 같이 클래스를 사용할 수 있고 클래스 이름은 파스칼 케이스로 클래스의 이름을 표기하면 된다. 크래스는 0 개 이상의 멤버 함수를 포함하며 모든 멤버 함수의 첫 번째 인자는 해당 클래스의 인스턴스를 의미하는 self로 정의해야 한다.
메서드의 이름이 언더 바로 시작하는 경우, 클래스 밖에서 호출을 하면 안되는 private 메서드를 의미한다. init , repr 등 이름의 앞 뒤로 언더바가 두개 씩 추가된 메서드는 dunder(double_UNDERscore)메서드라고 부르며 특별한 기능을 가지고 있다.
또한 부모 클래스에서 기느을 상속받을 수 있는 서브클래스를 종종 사용할 수 있다.

class CountingClicker:
    def __init__(self, count = 0)
        self.count = count

    def __repr__(self, num_times = 1):
        return f"CountingClicker(count={self.count})"

    def click(self, num_times = 1):
        self.count += num_times

    def read(self):
        return self.count

     def reset(self):
         self.count = 0 


class NoResetClicker(CountingClicker):
    def reset(self):
        pass

clicker2 = NoResetClicker()
assert clicker2.read() == 0
clicekr2.reset()
assert clicker2.read() == 1, "reset shouldn't do anything"

2. 이터레이너와 제너레이터

이터레이터는 반복가능한 객체이고, 제너레이터는 이터레이터의 한 종류로 모든 데이터의 위치를 가지지 않고 yeild를 통하여 위치를 정하여 반복하는 객체이다. 주로 yield를 사용하고 이를 사용하는 이유는 메모리를 효율적으로 사용하기 위해서이다.

def generate_range(n):
    i = 0
    while i < n:
        yeild i
        i += 1

for i in generate_range(10):
    print(f"i: {i}")

사실 range 자체가 제너레이터로 만들어졌기 때문에 이렇게 따로 만들 필요는 없다.

종종 리스트나 제너레이터에서 항목을 하나씩 확인해 볼 경우, 항목의 순서(index)를 반환하고 싶을 때가 있다. 이럴 때는 enumerate 함수를 사용 하면 된다.

for i, name  in enumerate(names):
    print(f"name {i} is {name}")

3. 난수 생성

주로 random 모듈을 사용, 만약 수도 랜덤(pseudo random)한(결정론적으로 동일한) 난수를 계속 사용하고 싶다면 random.seed를 통해 매번 고정된 난수를 설정하면 된다.

import random
random.seed(10)

four_uniform_randoms = [random.random() for _ in range(4)]

인자가 1개 혹은 2개인 random.randrange메서드를 사용하면 range()에 해당하는 구간 안에서 난수를 생성할 수 있다.

random.randomrange(10)
random.randomrange(3, 6)
  • random.shuffle은 리스트의 항목을 임의 순서대로 재정렬 해준다.
  • random.choice는 리스트의 리스트에서 임의의 항목을 선택한다.
  • random.sample을 사용하면 리스트에서 중복이 허용되지 않는 임의의 표본 리스트를 만들 수 있다.

만약 중복이 혀용되는 임의의 표본 리스트를 만들고 싶다면 random.choice 메서드를 여러번 사용하면 된다.

four_with_replacemeont = [random.choice(range(10)) for _ in range(4)]
print(four_with_placement)

4. 정규표현식

파이썬도 다른 프로그래밍 언어와 같이 "import re" re라이브러리를 통해 정규표현식을 사용하여 문자열을 찾을 수 있다.

5. zip과 인자 언패킹

두 개 이상의 리스트를 서로 묶어 주고 싶을 때 zip은 여러개의 리스트를 서로 사응하는 항목의 튜플로 구성된 리스트로 변환한다. 묶인 리스트는 다시 풀어 줄 수도 있다.

list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]

[pair for pair in zip(list, list2)]
letters, numbers = zip(*pairs)

별표(*)는 인자 언패킹(argument unpacking)을 할 때 사용되는 문법으로, 이를 사용하면 pairs 안의 항목들을 zip함수에 개별적인 인자로 전달해준다.

6. args 와 kwargs

특정 함수 f를 입력하면 f의 결과를 두 배로 만드는 함수를 반환해 주는 고차 함수를 만든다면,

def double(f):
    def g(x):
        return 2 * f(x)
    return g

def f1(x):
    return x + 1

g = doubler(f1)
assert (g3) == 8

위 와 같은 방식으로 사용할 수 있지만, 두 개 이상의 인자를 받는 함수의 경우에는 다음과 같은 문제가 발생한다.

def f2(x, y):
    return x + y

g = doubler(f2)
try:
    g(1, 2)
except TypeError:
    print("as defined, g only takes one argument")

위의 문제를 해결하기 위해 임의의 수의 인자를 받는 함수를 만들어 줘야 한다. 앞서 설명한 인자 언패킹을 사용하면 마법같이 임의의 수의 인자를 받는 함수를 만들 수 있다.

def magic(*args, **kwargs):
    print("unnamed args:", args)
    print("keword args:", kwargs)

magic(1, 2, key="word", key2="word2"

다음과 같은 결과가 출력된다.
unnamed args:(1, 2)
keword args: {'key': 'word', 'key2':'word2')

위에서 args는 이름이 ㅇ벗는 인자로 구성된 튜플이며, kwargs는 이름이 주어진 인자로 구성된 딕셔너리이다. 반대로, 정해진 수의 인자가 있는 함수를 호출할 때도 리스트나 딕셔너리로 인자를 전달할 수 있다.

def other_way_magin(x, y, z):
    return x + y + z

x_y_list = [1,2]
z_dict = {"z": 3}
assert other_way_magic(*x_y_list, **z_dict) == 6, "1 + 2 + 3 should be 6"

코드의 가독성을 위해 함수에서 필요한 인자를 모두 표시해주는 것이 좋고, 꼭 필요한 경우에만 args, kwargs를 사용해야 한다.

7. 타입 어노테이션

최근 파이썬도 타입을 명시하기 시작했다. 아무런 기능도 없지만 타입 명시는 프로그래밍 언어를 활용해 본 사람이라면 생각보다 필요한 부분이라는 것을 알 수 있을 것이다.

def add(a: int, b: int) -> int
    return a + b

def ugly_function(vlaue: int, operation: Union[str, int, float, bool]) -> int:
    ...

int, bool, float 같은 기본적인 객체는 타입을 바로 명시해 주면된다. 리스트의 경우에는 어떻게 타입을 명히사는 게 좋을까? 만약 float객체를 갖고 있는 리스트가 있다면, typing 모듈을 사용하면 구체적으로 타입을 명시할 수 있다.

from typing import List

def total(xs: List[float]) -> float:
    return sum(total)

종종 변수의 타입이 명확하지 않은 경우 힌트를 추가할 수 있다.

from typing import Optional

vlaues: List[int] = []
best_so_far: Optional[float] = None

'IT > Data Analysis' 카테고리의 다른 글

확률론과 통계학  (0) 2024.08.15
선형대수  (0) 2024.08.12
데이터 시각화  (0) 2024.08.11
파이썬 속성강좌_기초  (0) 2024.08.11
데이터 과학  (0) 2024.08.11