본문 바로가기

반응형

Computer/Python

(57)
ModuleNotFoundError 와 ImportError 큰 프로젝트를 구현하다보면 비슷한 기능을 수행하는 클래스와 함수를 별도의 디렉토리, 파일로 refactoring 하고 메인 디렉토리에서 main.py (혹은 test.py)를 수행하게 됩니다. 보통 파이썬 패키지를 구현하면 메인 working directory 에서 소스코드가 담긴 src 디렉토리, 예시가 담긴 examples 디렉토리, 테스트를 위한 tests 디렉토리를 구성하게 되는데요, src 디렉토리 이름을 Figure 1과 같이 working 디렉토리 이름과 같이 정하는 경우도 흔히 있습니다. Figure 1은 HongLearning이란 패키지 예시이고 소스 코드를 HongLearning 디렉토리 안에 구현했다고 가정했을 때의 디렉토리 트리 구조입니다. 현재 current working dire..
Vectorization Numpy 연산이 매우 빠른 이유는 무엇일까요? 다음과 같이 50만개의 배열에 대해 numpy array 연산으로 1을 더하는 것과 모든 element를 for 문으로 순회하면서 1을 더하는 것은 시간 상의 명백한 차이가 있습니다. Numpy 연산이 수십 배나 빠르죠. import numpy as np from timeit import Timer li = list(range(500000)) nump_arr = np.array(li) def python_for(): return [num + 1 for num in li] def numpy_add(): return nump_arr + 1 >>> print(min(Timer(python_for).repeat(10, 10))) >>> print(min(Timer..
"is" vs "==" [개발 잡학/Python] - 파이썬과 객체 파이썬에서 "is"와 "=="는 두 개의 객체가 같은지를 True/False로 반환하는 operator 입니다. 정확하게는 "is"는 identity operator, "=="는 equality operator 인데요, 이번 포스트에서는 이 두개의 operator의 차이를 알아보도록 하겠습니다. "is" "is"나 "is not"은 두 객체의 identity, 메모리 주소가 동일한지를 비교합니다. 즉, 두 객체가 메모리 상에서 같은 곳에 위치하느냐 판단하는 operator인 것이죠. id() 메소드를 이용하면 객체의 메모리 주소를 알 수 있고 (CPython) id() 같은 built-in 함수조차 메모리 상의 주소를 가지고 있음을 알 수 있습니다. >>> h..
파이썬 실수 내림/올림 파이썬의 math 내장 라이브러리의 floor/ceil 함수는 각각 인자로 주어진 실수를 내림/올림하는 함수로서 실수를 받아 정수를 리턴합니다. from math import ceil, floor, log10 >>> floor(1.025), ceil(1.025) (1, 2) 하지만 실수에 대해서 소수점 몇번째 자리에서 내림/올림 등을 수행하고 싶을 때가 있는데요, 이러한 경우에는 floor/ceil 함수를 이용해 약간의 수학적인 트릭을 이용해야 합니다. 먼저 소수점 자리에 대해서 처음으로 0이 아닌 자리에 대해 내림/올림을 수행해보도록 하겠습니다. 예를 들어 0.001575라면 0.002이 되는 것이죠. 따라서 소수에 대해서 처음으로 0이 아닌 자리를 찾아야하는데 이는 밑이 10인 로그를 취하고 floo..
Shallow copy vs Deep copy 파이썬에서의 assignment operation (=)은 객체의 복사본을 만들지 않습니다. 메모리 상에 존재하는 하나의 객체에 대해 다른 변수이름을 binding 하는 것 뿐이죠. 따라서 리스트와 같은 변경 가능한 객체에 대해서 b=a 를 수행하고 a의 원소값을 변경하면 b의 값 또한 마찬가지로 변경됩니다. >>> a = [1,2,3,4] >>> b = a a[3] = 100 >>> a [1, 2, 3, 100] >>> b [1, 2, 3, 100] 하지만 문자열, 정수와 같은 불변 객체에 대해서는 적용되지 않습니다. a의 값을 다른 값으로 변경하면 a는 메모리 상의 다른 객체를 참조하고 b는 그대로 원래 객체를 참조합니다. >>> a = 10 >>> b = a >>> b 10 >>> a = 'abc'..
List Subtraction 두 개의 리스트 $x, y$가 있을 때 $x$ 리스트 원소 중 $y$ 리스트에 속한 원소를 제거하고 싶습니다. 예를 들면 다음과 같은 빼기 연산 (-)를 수행하고 싶은겁니다. >>> x = [1,2,3,4,5,6,7,8,9,0] >>> x [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] >>> y = [1,3,5,7,9] >>> y [1, 3, 5, 7, 9] >>> x - y # (should return [2,4,6,8,0]) 하지만 리스트 자료구조에 대해서는 빼기 연산 (-)를 지원하지 않으므로 다음과 같은 에러가 발생합니다. Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s)..
파이썬의 GIL 사용 이유 파이썬 구현체 CPython의 GIL (Global Interpreter Lock)은 파이썬 바이트코드를 실행할 때, 여러 쓰레드 중 하나의 쓰레드만이 파이썬 객체에 접근할 수 있게 하는 mutex (mutual exclusive) 로서 하나의 프로세스의 공유 리소스를 하나의 쓰레드만이 점유하게 하는 장치입니다. 따라서 파일 읽기/쓰기, 네트워크 통신 등과 같은 I/O 작업이 아닌 행렬연산, 이미지처리 등 CPU를 많이 사용하는 작업에 대해서는 파이썬의 멀티쓰레드로는 성능향상을 기대할 수 없는데요, 다음 코드를 보면 다중쓰레드가 락 (mutex)의 획득, 해제에 따른 오버헤드로 인해 실행 시간이 더 길게됩니다. # single_threaded.py import time from threading impo..
Decorator 에서 함수 디폴트 인자 파악 방법 데코레이터는 자신이 감싸고 있는 함수가 호출되기 전과 후에 코드를 추가로 실행하는 파이썬의 문법으로 여러 함수에 대해 동일한 기능을 수행시키고 싶을 때 주로 사용합니다. 다음 코드와 같이 장식할 함수를 인자로 받아 wrapper 함수에서 인자로 받은 함수를 수행하고 wrapper 함수가 반환되므로 sample 함수 호출 시 전달한 인자는 wrapper 함수의 인자 *args, **kwargs가 됩니다. def trace(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) print(f'{func.__name__}') print(f'Arguments: {args!r}, Keywords: {kwargs!r}', end = '') retur..

반응형