언어 Language/파이썬 Python 27

[디자인 패턴] 추상 팩토리 패턴과 파이썬 예제 코드

추상 팩토리 패턴(Abstract Factory Pattern)은?생성 패턴 중 하나로 추상 팩토리 패턴은 관련성 있는 여러 제품군을 한 번에 생성할 수 있도록 도와주는 패턴이다. 팩토리 메소드 패턴은 단일 제품군을 다루지만 추상 팩토리 패턴은 여러 제품군을 한 번에 생성한다. 언제 사용하는가?서로 관련 있는 여러 객체를 한 번에 생성하고 싶을 때 사용한다. 팩토리 메소드 패턴은 예를 들면 소셜 로그인처럼 하나만 다루지만, 추상 팩토리 패턴은 로그인 서비스와 결제 서비스처럼 연관된 여러 제품군을 함께 다루는데 적합하다. 카카오 플랫폼에서는 카카오 로그인과 카카오페이를, 네이버 플랫폼에서는 네이버 로그인과 네이버페이를 함께 사용해야 한다. 이 경우 추상 팩토리 패턴을 사용하면 카카오 제품군과 네이버 제품군..

[디자인 패턴] 팩토리 메소드 패턴과 파이썬 예제 코드

팩토리 메소드 패턴(Factory Method Pattern)은?생성 패턴 중 하나로 팩토리 메소드 패턴은 객체 생성을 서브클래스에 위임해서, 클라이언트 코드가 구체 클래스에 직접 의존하지 않도록 만드는 생성 패턴이다. 객체 생성 코드를 분리함으로써 새로운 타입이 추가되더라도 기존 클라이언트 코드를 수정할 필요 없이 확장할 수 있다. 언제 사용하는가?팩토리Factory란 이름처럼 자동차 공장에서 세단, SUV, 트럭 등 다양한 차를 생산하는 경우를 떠올릴 수 있다. 이처럼 상황에 따라 다른 객체를 생성해야 할 때 유용하다.예를 들어, 소셜 로그인 연동 기능을 구현할 때, 카카오 로그인, 네이버 로그인, 구글 로그인 등 다양한 외부 서비스와 연동이 필요하다. 이때 팩토리 메소드 패턴을 사용하면 객체 생성과..

[디자인 패턴] 심플 팩토리 패턴과 파이썬 예제 코드

심플 팩토리 패턴(Simple Factory Pattern)은?생성 패턴 중 하나로 심플 팩토리 패턴은 클라이언트가 입력한 인자에 따라 객체를 분기해서 생성하는 패턴이다. 클라이언트는 직접 객체를 생성하지 않고, 공장 역할을 하는 클래스에 생성을 위임한다. 언제 사용하는가?팩토리Factory란 이름처럼 자동차 공장에서 세단, SUV, 트럭 등 다양한 차를 생산하는 경우를 떠올릴 수 있다. 이처럼 상황에 따라 다른 객체를 생성해야 할 때 유용하다. 예를 들어, 소셜 로그인 연동 기능을 구현할 때, 카카오 로그인, 네이버 로그인, 구글 로그인 등 다양한 외부 서비스와 연동이 필요하다. 이때 심플 팩토리 패턴을 사용하면, 클라이언트는 어떤 클래스가 생성되는지 알 필요 없이 공장 클래스(Factory Class..

[디자인 패턴] 싱글턴 패턴과 파이썬 예제 코드

싱글턴 패턴은?생성 패턴 중 하나로 전역에서 접근 가능한 하나의 객체를 제공하는 패턴이다. 언제 사용하는가?로깅이나 데이터베이스 작업, 설정값처럼 단일 객체가 필요한 경우에 사용한다.설정값을 예로 들어보자. 설정은 프로그램 전역에서 사용하며 당연히 같은 값을 반환해야 한다. 굳이 여러 객체를 만들어서 사용해야 할 이유가 없다. 사례파이썬 웹프레임워크인 장고의 설정 사례를 살펴보자.장고에서 설정값을 불러와서 사용할 때from django.conf import settings식으로 불러와서 사용하게 된다. 이 settings가 싱글턴 패턴으로 되어 있다. django/conf/__init__.py 파일을 보면 아래처럼 선언되어 있다.settings = LazySettings() 출처: https://gith..

Q. 파이썬 비공개 패키지를 만들고 다른 프로젝트에서 쓰는 방법은?

언제 비공개 패키지가 필요한가?팀 내에서 여러 저장소에서 사용하는 공통 모듈들이 있다. 공통 모듈을 한 저장소에 모아두고 오픈 소스로 공개하면 쉽게 쓸 수 있다. 하지만 보안상 이유로 공개할 수 없다면 비공개 패키지를 사용하게 된다. 1. Github에서 비공개 저장소 만들기비공개 저장소를 하나 만들자. private-package로 하나 만들었다. 이름은 원하는대로 만들면 된다. 실습을 위해서 아주 간단한 더하기 메소드만 갖고 있는 Calculator 클래스를 하나 추가하자. class Calculator:    def sum(self, a, b):        return a + b pyproject.toml은 아래처럼 간단히 입력하자. name은 패키지명인 calculator와 동일하게 적어야 한다..

Q. 파이썬 비공개 패키지 저장소 만들 때 주의사항은?

A. 공개 패키지와 마찬가지로 최상위 패키지는 하나만 있어야 하고, pyproject.toml을 작성해야 한다. tag를 추가하는 것을 추천한다. 비공개 패키지는 언제 사용할까?기업 규모가 커지게 되면, 서비스가 늘어난다. 예를 들어서 장고 프레임워크를 사용한다면, 장고 프레임워크를 사용하는 서비스가 여러 개가 되며, 당연히 저장소도 여러 개가 된다. 이때 유틸리티 성격의 공통 모듈이 늘어나게 된다. slack 메시지 처리, AWS S3 저장 관련 등 오픈 소스 패키지에서 약간만 수정해서 공통으로 쓰는 것들이 그런 예다. 이런 공통 모듈을 비공개 패키지로 분리하면 공통 모듈을 한 곳에서 관리할 수 있어서 생산성이 올라간다. 공개 패키지로 하면 더 편하지만 외부 공개할 수 없는 모듈도 존재할 때 비공개 패..

Q. 파이썬Python 기본 반올림 함수인 round(0.5)의 결과는?

A. 0이다. 중고등학교 수학시간에 배운 반올림 방식으로 생각하면 1이어야 할 거 같은데 0이 나온다. 그 이유는 파이썬 round는 우리가 수학시간 때 배운 사사오입 방식 4이면 내리고 5이면 올리는 게 아니라 오사오입 방식이기 때문이다. (참고: 반올림 위키백과)오일 때 버리고 그 다음 오는 올린다. 그래서 round(0.5) -> 0, round(1.5) -> 2가 된다. 결과가 짝수로 나온다. round(0.5) -> 0 round(1.5) -> 2 round(2.5) -> 2 round(3.5) -> 4로 가까운 짝수값이 나온다. 소숫점 첫째 자리에서 반올림해봐도 특이하다. round(0.01, 1) -> 0.0 round(0.05, 1) -> 0.1 round(0.15, 1) -> 0.1 ro..

Q. Python에서 함수나 구문의 속도를 측정하는 방법은?

A. cProfile을 이용해서 측정할 수 있다.출처: 파이썬 프로파일러 인라인 리스트 예아래 같은 코드를 추가하고 실행해보자.import cProfile def get_number_list(): number_list = [] for i in range(1000000): number_list.append(i) return number_list cProfile.run(statement="get_number_list()") cProfile.run(statement="[i for i in range(1000000)]") 실행결과 같은 숫자 배열을 얻는 경우인데, 인라인으로 처리한 경우가 약 4배 빠른 것을 확인할 수 있다. not A and not B와 not (A or B) 비교 예not A and not ..

Q. Pycharm에서 파이썬 Black 코드 포맷 자동 적용하는 방법은?

A. File Wathcer에 등록하면 된다. 출처: Black documentation: PyCharm/IntelliJ IDEA As file watcher Black 공식 문서에서는 black 적용 방법으로 As local server, As external tool, As file watcher 3가지 방법을 제시하고 있다. 이 중에서 File watcher가 자동 적용되어서 편하다. black 설치 MacOS 기준이다. 윈도우도 큰 차이는 없으니 위 공식 문서를 참고하자. $ pip install black $ which black black을 설치하고 which로 black 설치 위치를 확인할 수 있다. 내 경우는 파이썬 가상환경을 따로 만들어서 설치했기 때문에 아래와 같다. /Users/tap..

Q. staticmethod와 classmethod 데코레이터decorator의 차이는?

A. staticmethod는 클래스에 접근이 안 되고, classmethod는 접근이 된다. 메소드 위에 두 데코레이터를 사용할 경우 객체 생성 없이 바로 메소드를 사용할 수 있다. 예제쉽게 이해할 수 있는 예는 아래와 같다.class Calculator: PI = 3.141592 def sum(self, num1, num2): return num1 + num2 @staticmethod def static_sum(num1, num2): return num1 + num2 def get_circle_area(self, radius): return radius * radius * self.PI @classmethod def class_get_circle_area(cls, radius): return radi..

Q. 파이썬Python에서 타입 힌트Type hints를 적으면 타입이 변경될까?

A. 아니다. 변경되지 않는다. 아래처럼 text란 변수의 type을 int로 선언했다. 값은 "hello!"를 저장하고, type을 찍어보면 어떻게 될까? text: int = "hello!" print(type(text)) 입력값인 "hello!"의 타입인 str이 된다. int가 아니다. 에러도 발생하지 않는다. 너무 단순한 예라 그런 거고 다른 경우는 다를 거 같다고 생각할 수 있다. DRF(Django Rest Framework)에서 아래처럼 테스트를 해보자. request를 엉뚱하게 str이라고 선언한다. 그리고 type을 확인한다. 역시나 원래 타입인 rest_framework.request.Request로 나오는 것을 확인할 수 있다. 타입 힌트는 말 그대로 힌트다. 정적 타입 언어인 다른..

Q. 파이썬에서는 어떤 값들이 False일까?

A. 0, '', (), [], {}, set(), range(0), None 등이 False다. 공식 문서 설명은 다음과 같다. constants defined to be false: None and False. zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1) empty sequences and collections: '', (), [], {}, set(), range(0) 출처: Truth Value Testing, Python Documentation 아래 값들은 모두 False다. bool(0) bool('') bool(()) bool([]) bool({}) bool(set()) bool(range(0)) bool(None) bo..

Q. 파이썬 타임존 유명 pytz 팩키지의 서울 타임존이 LMT+08:28:00으로 나오는 이유는?

아래처럼 코드를 실행해보면 from pytz import timezone seoul = timezone('Asia/Seoul') seoul 엉뚱한 결과가 나온다. LMT+8:28:00 STD 아니 서울은 시차가 +9시간인데 왜 +8:30도 아니고 +8:28일까? A. 대한제국 이전을 기준으로 한 것이다. 엄청 많이 쓰는 pytz. 공식 파이썬 팩키지 같지만 아니다. 그냥 개인 프로젝트다. pytz 깃허브 들어가보면 생각보다 별 숫자도 적어서 놀라게 된다. 바로 별을 눌렀다! pytz는 Time Zone Database를 사용하고 있다. 여기 사이트 가서 데이터를 받아서 압축을 풀어서 asia를 열어보자. 아래 같은 정보를 확인할 수 있다. # ZoneNAMESTDOFFRULESFORMAT[UNTIL] Z..

Q. Python에서 for문을 돌면서 실행하는 코드를 한 줄로 작성할 수 있을까?

A. 가능하다. 변수에 저장하지 않는 코드라면. 이렇게 두 줄인 코드를 for num in range(10): print(num) 아래처럼 한 줄로 적을 수 있다. [print(n) for n in range(10)] 딱히 리스트를 만들 것은 아니지만 [ ]로 감싸주면 실행가능하다! [ ]를 없애면? 당연히 구문syntax 에러가 난다. 함수를 선언해서 할 수도 있다. 아래처럼 하는 것도 가능하다. def print_num(num): print(num) [print_num(n) for n in range(10)] 변수에 할당하는 건 안 된다. 구문 에러가 발생한다. 아래처럼 하고 싶을 수도 있지만 안 된다. sum = 0 [sum += n for n in range(10)] 뭔가 할당하고 저장하기만 하고..

Q. 파이썬에서 객체에 새로운 속성이 임의로 추가되지 않도록 하고 싶다면?

A. pydantic을 사용하면 된다. from pydantic import BaseModel class Person(BaseModel): name: str = '' gender: str = '' if __name__ == '__main__': john = Person() john.age = 23 print(john.age) pydantic을 사용하면 아래처럼 에러가 난다. john.age = 23 File "pydantic/main.py", line 357, in pydantic.main.BaseModel.__setattr__ ValueError: "Person" object has no field "age" 같은 코드에서 pydantic BaseModel만 제거하면 잘 출력된다. 파이썬 객체의 경우 ..

Q. 파이썬으로 개발할 때 타입 힌트type hints를 쓰면 좋은 점은?

A. 개발자 실수로 인한 오류가 확 줄어든다! 파이썬은 동적 타입 언어Dynamically Typed Language 그때 그때 알아서 타입이 바뀌는 걸 동적 타입 언어라고 한다. 정적 타입 언어Statically Typed Language인 C나 자바는 변수를 선언할 때 타입부터 선언해야 한다. 하지만 파이썬은 동적 타입 언어니까 변수를 선언할 때 타입을 선언하지 않는다. message = "Hello World!" print(message) message = 7 print(message) 위처럼 그냥 변수 = 문자열 하면 해당 변수에는 문자열이 담긴다. 그 다음에 숫자를 변수에 저장해도 전혀 문제 없이 잘 작동한다. 웹 개발 때 많이 쓰는 자바스크립트도 동적 타입 언어다. 동적 타입 언어 문제 알아서..

PDF를 텍스트로 바꿔주는 pdfminer.six, pypdf2, pdfplumber 비교해보기

여기 2030년 자율주행 서비스 일상화, 미래 모빌리티 선도국가 도약란 국토교통부의 보도자료가 있다. 보도자료는 보통 PDF와 HWP 파일로 공개된다. 이 중 PDF를 텍스트로 변경해보고 싶다. 많이 쓰는 것 중심으로 테스트를 해봤다. pypdf2, pdfminer.six, pdfplumber 3개다. 위 pdf 중 두 번째 쪽은 아래와 같다. 아래 PDF를 텍스트로 변경해봤다. pypdf2 2쪽을 하고 싶었으니 아래처럼 index는 1이 된다. from PyPDF2 import PdfReader FILE_PATH = "220609(석간)_강남에서_자율주행_택시_달린다(첨단자동차과).pdf" INDEX_OF_PAGE = 1 def text_to_txt_file(text, file_name): with o..

Q. 파이썬에서 데이터를 객체로 맵핑하는 방법은?

A. 여러가지 방법으로 가능하다. 기본 __init__을 활용할 수도 있고, dataclasses, pydantic 등을 활용해서 할 수도 있다. 데이터를 받아서 데이터 모델 클래스의 객체object로 맵핑mapping하는 경우는 정말 많이 필요하다. 그렇지 않으면 일일이 변수로 만들거나 딕셔너리로 접근해야 하는데 너무 번거롭기 때문이다. 데이터를 객체로 만들어주는 팩키지나 라이브러리를 보통 객체 맵퍼 Object Mapper라고 부른다. 예를 들면 자바의 Jackson 같은 경우다. 파이썬에서는 어떻게 객체 맵핑을 할 수 있을까. 1. 가장 기본적인 방법 __init__ 을 활용하는 방법이다. class User: def __init__(self, name, phone, birthday): self.n..