Python
상속 안티 패턴
원하는 데이터 객체를 만들기 위해 많은 비용을 들이지 말자. 다음 예를 보자 class TransactionalPolicy(collections.UserDict): """잘못된 상속의 예""" def change_in_policy(self, customer_id, **new_policy_data): self[customer_id].update(**new_policy_data) 이 클래스는 고객의 정책에 접근해 정책을 바꾼다는 목적에는 부합할 수 있으나, 상속의 안티패턴을 보여주고 있다. 계층 구조가 잘못됐다. 기본 클래스에서 새 클래스를 만드는 것은 개념적으로 확장되고 세부적인 것이다라는 것을 뜻한다. 하지만 해당 데이터 객체는 Dict를 상속하면서 Dict의 개념을 확장했다기 보단 필요한 몇몇 부분(고..
가상파일시스템 pyfakefs 를 통해 테스트 코드 작성하기
해당 디렉토리의 파일을 모아주는 util 함수를 생성하고 테스트 하고 싶었다. 하지만 실제로 폴더를 만들고 파일을 만드는 건 이치에 맞지 않다고 판단해서 이를 해주는 라이브러리가 없을까 찾아보다가 pyfakefs 를 찾았다. 공식문서는 요기 pyfakefs pyfakefs implements a fake file system that mocks the Python file system modules. pypi.org 사용 방법은 간단했다. 해당 라이브러리를 다운받고, pytest 의 fixture를 다루듯이 테스트 함수에서 매개변수로 다루면 되었다. 아래는 pyfakefs 를 활용해 테스트 코드를 짜본 것이다. def test_collect_file_path(fs) -> None: """ 해당 디렉토리의..
![](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyzTlS%2Fbtr3S03IKSw%2FIJVk7havqH5d64HKam60RK%2Fimg.png)
Poweshell 환경에서 poetry 와 pyenv로 가상환경 세팅하기
코딩을 하기 전 개발 환경을 세팅하는 것은 중요하다. 솔직히 1인 개발이면 상관없겠지만, 팀 단위로 개발 환경을 공유해야 하는 경우 환경을 맞춰야 한다. 따라서 이러한 가상환경을 세팅하기 위해 pyenv와 poetry를 활용해 파이썬 버전 관리와 패키지 버전을 관리해 보자. 그리고 난 window 환경이라 더 애먹었기 때문에 정보 공유차원에서 기록을 남긴다. Powershell에서 pyenv 설치하기 pyenv를 설치하는 과정도 험난했다. 참고한 사이트는 아래에 참조를 걸어놨다.(고마운 분들...) 우선 powershell을 관리자용으로 열고 아래의 명령을 넣자 Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv..
스택프레임, 빅오
스택 프레임 함수가 호출되면 스택 프레임이라는 공간이 생긴다. 이 스택 프레임에는 함수 실행에 필요한 지역변수들이 할당된다. def add_two(a,b): c = a + b # 4 return c a = 10 # 1 b = 20 # 2 result = add_two(a, b) # 3 print(result) #1과 #2는 프로그램이 시작되면서부터 끝날 때까지 메모리에 유지되는 전역변수이다. #3에서 a와 b를 인수로 전달하고 add_two 함수를 호출하면 내부적으로 ‘스택 프레임’이라는 내부 공간이 생기고, 그 공간에 add_two 함수 내부에 있는 매개변수 a, b와 그 결괏값을 담을 지역 변수 C가 저장된다. 스택 프레임은 메모리에 생성되는데 생성될 수 있는 크기에 한계가 있다. 이때 발생하는 에러..
결합과 추상화 - 3
2023.02.13 - [Python] - 결합과 추상화 - 2에 이어 가 보자. 의존성 주입과 가짜를 사용해 에지투에지 테스트 단위 테스트가 어느 정도 모이다 보면 시스템의 큰 덩어리를 한 번에 테스트하려고 할 것이다. 이때 엔트투엔드 테스트로 돌아갈 수도 있다. 하지만 엔트투엔드 테스트는 작성하거나 유지보수하기 어렵다. 대신 전체 시스템을 한 번에 테스트하되, 가짜 I/O를 사용하는 일종의 에지투에지 테스트를 자주 작성하자. 명시적 의존성: def sync(source, dest, filesystem=FileSystem()): # 최상위 함수는 이제 reader와 filesystem이라는 두 가지 의존성을 노출한다. source_hashes = filesystem.read(source) # reade..
결합과 추상화 - 2
2023.02.09 - [분류 전체보기] - 결합과 추상화 - 1 이전 글에 이어서 쓰기 파일 입출력과 관련한 테스트를 어떻게 작성해야 할까? 시스템에서 트릭이 적용된 부분을 분리해서 격리하고, 실제 파일 시스템 없이도 테스트할 수 있게 해야 한다. 외부 상태에 대해 아무 의존성이 없는 코드의 '핵'을 만들고, 외부 세계를 표현하는 입력에 대해 이 핵이 어떻게 반응하는지 살펴보자. 먼저 코드에서 로직과 상태가 있는 부분을 분리하자. 이제 최상위 함수는 거의 아무 로직도 들어있지 않고, 입력을 수집하고 로직(함수형 핵)을 호출한 다음 출력을 적용하는 명령형 코드의 나열로 바뀐다. def sync(source, dest): # 명령혈 셀 1단계: 입력 수집 source_hashes = read_paths_a..
Pytest - 3. Monkeypatching functions
1. Monkeypatching 이란? 공식 문서에는 다음과 같이 Monkeypatching을 설명한다. 항상 특정 값을 반환하도록 만들 때 monkeypatch를 사용하라고. 아래의 예에서 monkeypatch.setattr은 Path.home을 패치하는 데 사용되므로 테스트가 실행될 때 ('/abc')가 항상 사용된다. 이것은 테스트 목적으로 실행 중인 사용자에 대한 의존성을 제거한다.(사용자의 환경에 따라 테스트 결과가 달라질 수 있는데 이를 삭제하기 위한 방법) monkeypatch.setattr은 패치된 함수를 사용할 함수를 호출하기 전에 호출해야 한다. 테스트 기능이 완료되면 Path.home 수정이 실행 취소된다. # contents of test_module.py with source co..
Pytest - 2. Fixture 알아보기
어제에 간단하게 예제를 살펴보았다. 이번에는 Fixture의 들어가는 인수 등을 살펴보자. 1. Autouse autouse를 True로 설정하면, 별도 요청 없이 모든 테스트 함수에서 해당 fixture를 사용할 수 있다. Sometimes you may want to have a fixture (or even several) that you know all your tests will depend on. “Autouse” fixtures are a convenient way to make all tests automatically request them. This can cut out a lot of redundant requests, and can even provide more advanced f..
Pytest 사용하기 - 1. 간단한 예제
pytest를 활용하여 테스트 코드를 짜보자 설치 우선 가상환경에 진입해서 pytest를 install 하자 pip install pytest 테스트 파일 작성하기 1. 함수형 타입 그런 다음 test_ 로 시작하는 테스트 코드를 실행한 파이썬 실행 파일을 만들자. # test_demo.py def test_success_sum(): x = 4 y = 3 assert x + y == 7 def test_fail_sum(): x = 4 y = 3 assert x + y != 6 각각 더하기를 실행했을 때 성공 케이스(test_success_sum())와 합산이 잘못된 케이스(test_fail_sum())를 작성하였다. 이렇게 작성해도 테스트는 잘 동작하지만, x와 y는 두 함수에서 공통적으로 사용하고 있다..
파이썬으로 배우는 자료구조 핵심 원리
파이썬으로 배우는 자료구조 핵심원리 스택프레임 함수가 호출되면 메모리에는 스택 프레임이라는 공간이 생긴다. 여기에는 함수 실행에 필요한 지역 변수들이 할당된다. 스택 프레임의 생성 시기는 함수를 호출했을 때고, 소멸 시기는 함수 실행이 종료되었을 떄이다. 스택 프레임은 메모리에 생성되는데 생성될 수 있는 크기에 한계가 있다. 그러므로 계속 쌓인다면 언젠가는 최대 한계치에 도달할 수밖에 없다. 이 때 발생하는 에러가 Recursion Depth 에러이다. 재귀 함수를 스택 프레임의 관점에서 바라보면 상태 정보를 가지고 있는 지역 변수는 서로 다른 스택프레임에 저장된다. 실행 결과는 서로 다른 스택 프레임에 있는 지역 변수에 저장된다. 이때 기저 사례를 두지 않으면 계속 호출이 일어나고 스택프레임이 저장되는..