라벨이 python인 게시물 표시

Python의 빌트인 class들의 관계

이미지
파이썬의 iterable, iterator , generator, container의 관계를 설명할 때 많이 사용하는 그림이다. 나는 여기에 몇 가지를 좀 더 추가했다. generator는 iterator의 일종이나, 특별한 iterator라고 볼 수 있다. 게으른 factory와 같이 값을 미리 보유하고 있는 것이 아니라 필요에 따라 생성한다. python에서 제공하는 list, dict, ...등과 같은 객체들은, 선언과 동시에 안에 무엇을 담을지 결정하여 초기화시킬 수 있다. 그 코드에서 list, dict와 같은 객체들은 1,2,3,4와 같은 정수 배열을 담거나 key-value를 담은 container를 생성한다. python에서 제공하는 container 객체들 그리고 대부분의 container 객체들은 iterable, 순회할 수 있지만, 프로그래머 스스로 순회할 수 없는 container class를 구현할 수도 있다. int, float, double과 같은 자료형은 literal이며 container가 아니고, 순회할 수도 없다.  

CPython의 메모리 할당 시스템-1

이미지
CPython의 메모리 할당 시스템 Python의 기본 구현체 CPython의 메모리 할당 시스템은 C의 동적 메모리 할당 시스템 에 의존한다. CPython과 C의 동적 메모리 할당 시스템  중간 계층에 속하는 PyMemAPI 은 메모리 관리의 단순화 를 통해 프로그래머가 애플리케이션 로직에 집중할 수 있다. 메모리 관리의 단순화라고 하면은, 프로그래머가 직접 객체나 변수에 할당된 메모리를 해제하는 것이 아니라 (메모리 할당 해제 소스코드를 작성함으로써) 런타임 상에서 제공하는 GC, 참조 카운팅 기법을 사용하여 메모리를 자동으로 해제한다. 참조 카운팅 API - Py_INCREF : 값에 의존할 때 증가한다. - Py_DECREF : 값에 의존하지 않을 때 감소한다. 참조 카운트 값이 0이 될 때 자동으로 해제된다. 음수가 되기 시작한다는 것은 증감 연산의 짝이 맞지 않는다는 뜻이며 참조 카운팅에 결함이 생긴 것이다. 코드 로직 상 '순환 참조' 가 일어날 때도 생기는데 '순환 참조'를 해결하기 위한 GC가 Background에서 구동된다.

바이트코드 실행 과정 최적화로 python 3.14의 전체 실행 속도 향상

파이썬 3.14에서는 새로운 인터프리터가 추가된다. 이 새로운 인터프리터는 꼬리 호출 기반의 새로운 인터프리터다. 꼬리 호출은 C 컴파일러가 CPython 코드에서 수행하는 최적화 기법이다. 바이트코드 실행 과정 단계에서 최적화가 수행되어 전체 실행 속도를 높인다. 기존 코드 수정 없이 최대 30%의 성능 향상이 있을 것으로 기대된다. 꼬리 호출 최적화를 지원하는 c 컴파일러가 필요한데 MSVC, Clang 19 이상에서 가능하며 x86-64, aarch64 아키텍처를 지원한다. GCC는 지원 예정 새 인터프리터를 테스트 할 수 있는 파이썬 3.14의 첫번째 베타버전은 25년 5월 출시 예정 출처 https://www.cio.com/article/ 3824874/c%ec%96%b8%ec%96%b4% ec%99%80-%ec%86%8d%eb%8f%84-% ea%b2%a9%ec%b0%a8-%ec%a2%81% ed%9e%8c%eb%8b%a4%c2%b7%c2%b7% c2%b7-%ed%8c%8c%ec%9d%b4%ec% 8d%ac-%ec%83%88-%eb%b2%84%ec% a0%84-%ec%9d%b8%ed%84%b0%ed% 94%84.html

pypy3

Pypy3 Pypy = RPython으로 작성된 ( Interpreter + JIT compiler ) 2007년 구현된 python의 언어 구현 중 하나. c로 짜인 python의 기본 구현인 cpython과는 다르게 pypy는 python으로 python을 구현했다. 성능면에서 cpython을 능가하는 케이스가 많다. 코테에서  통과돼야하는 시간복잡도를 가진 로직인데도 불구하고 python3 인터프리터로 통과가 안 될 때 input 문법을 pypy3 문법으로 바꾸고 인터프리터로 pypy3를 사용하여 채점할 때 더 빠른 시간 내에 정답을 내는 것을 볼 수 있다. GCC( = C/C++로 만든 C/C++ 컴파일러 ) 와 같이 자신의 언어로 스스로를 구현하는 부트스트래핑을 사용하는데 부트스트래핑은 어셈블리어로 최적화를 하는 것보다 생산성이 좋다. pypy 실행 절차 RPython(= Restricted Python) 해석기를 Python으로 작성. 동적 타이핑 언어인 파이썬에서 엄격한 파이썬 문법으로 컴파일되게한다. Toolchain이 Rpython 함수를 그래프형태의 Control Flow Graph로 번역 다양한 언어를 지원하는 pypy-backend에서 - C - LLVM IR - pypy.js - jython - ironpython 등의 타깃 코드로 번역 해당 언어의 컴파일러가 실행파일로 컴파일하는 과정에서 CPython보다 효율적인 실행파일을 생성한다. JIT 컴파일을 통해 최적화된 기계어를 실행하며  python runtime 상에서 실행속도를 높인다. Pypy의 JIT와 CPython의 Interpreter JIT 컴파일 대 인터프리팅 JIT는 "hot code"를 찾아내는 등의 최적화 과정을 거친 기계어로 바꿈 Cpython은 한 줄 한 줄 읽어가며 stack based VM에서 python bytecode(.pyc)를 실행한다. python bytecode 이전에는 ast가 존재하는데 python 소스코드로부터 ast를 생성한다...

Python 2차원 배열 선언 시 * 연산자 사용

   예제 코드 a = [[1, 2, 3, 4], [5, 0, 7, 8], [4, 5, 2, 0]] b = [[0] * 4] * 3 c = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] print('a : ', a) print('b : ', b) print('c : ', c) print(a[1] == a[2]) b[1][1] = a[1][3] print(b) print(b[1] == b[2]) c[1][1] = a[1][3] print(c) print(c[1] == c[2]) 파이썬에서 2차원 배열 문제를 해결할 때 이중 리스트 구조의 데이터구조를 많이 활용한다. 0으로 초기화 되는 배열을 선언할 때, b처럼 선언하면 동일한 리스트로 인식되어버려서  b[0], b[1]의 eq 연산이 True를 반환하고 b[0][2]의 값을 변경해도 그대로 b[1], b[2]...에 반영된다. 때문에 * 를 지양하고 for 문을 돌면서 선언해주는 것이 바람직함. 출력 결과 a :  [[1, 2, 3, 4], [5, 0, 7, 8], [4, 5, 2, 0]] b :  [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] c :  [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] False [[0, 8, 0, 0], [0, 8, 0, 0], [0, 8, 0, 0]] True [[0, 0, 0, 0], [0, 8, 0, 0], [0, 0, 0, 0]] False

Python ABC-1

Python ABC abc의 역할 직접 class를 상속받지 않고도 isinstance, issubclass를 통해 subclass로 인지되는 가상 subclass 를 만들 수 있게한다. Python의 Abstract base class는 hasattr , magic method와 같은 방법보다 인터페이스를 정의함으로서  duck-typing을 보완 한다. isinstance(x, collections.Iterable)이 hasattr()나 그에 동등한 로직의 try...except 블록의 코드보다 더 이해하기 쉽다. (의도가 명확하다.) 즉, a라는 클래스가 A라는 상위 클래스의 인터페이스를 알맞게 구현하기만 한다면 a는 A의 subclass이다. abstract class/ 추상 클래스 세부 구현이 누락된 Class concrete class/ 구상 클래스 완전한 속성과 메서드가 구현된 Class Open-closed principle SOLID원칙 중 Open-closed 원칙을 만족한다. Open-closed원칙을 지키지 않은 코드는 <Open-closed principal> 기능을 추가할 때마다 기존 코드의 변경이 발생한다. - 새로운 class나 기능의 확장에 대해서는 열려있고 - 수정에 대해서는 폐쇄적이어야한다. 개방-폐쇄 원칙을 준수하는 코드는 객체지향의 장점인 다형성과 확장성을 만족한다. 잘 활용한다면 새로운 변경사항에 대해 유연하며 유지보수 비용 감소의 장점으로 이어진다. Polymorphic Open-closed principle 1990년경 Bertrand Meyer가 작성한 개방-폐쇄 원칙은 추상 인터페이스(abstracted interfaces)를  참조하기 위해 재정의되었다. abstract base class로부터 상속을 권고한다. 인터페이스 스펙은 상속을 통해 재사용될 수 있지만 재구현까지는 할 필요가 없다. 기존 인터페이스는 수정에 대해, 그리고 새 구현에 대해 폐쇄돼있으며 최소한의 abstracted...

Python Glossary

Python Glossary https://docs.python.org/3/glossary.html Python 공식 문서의 Glossary에서는  Python의 주요 용어들을 설명한다. 객체지향 파이썬을 배울 때면 객체지향 프로그래밍 트렌드에서 쓰이는 용어들을 접하게 되는데. Glossary를 정독하고 SOLID 원칙과 파이썬의 객체지향설계를 구현한다면 파이썬의 라이브러리 구조나, 모듈 설계 방법을 더 잘 이해할 수 있음.

Python SMTP + Application

소스코드 SMTP_SERVER = '' SMTP_ID = '' SMTP_PW = '' SMTP_SSL = True SMTP_PORT = 587 FROM_NAME = "" FROM_EMAIL = "" TO_EMAIL = "" import smtplib import datetime from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart def set_smtp_session(): try: # SMTP session smtp = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) smtp.set_debuglevel(True) # SMTP authentication smtp.ehlo() smtp.starttls() # TLS 사용시 호출 smtp.login(SMTP_ID, SMTP_PW) # 로그인 except Exception as e: print(f"smtp session error : {e}") return smtp def send_email(_session, sender, receiver): try: msg = MIMEText("test code") msg['Subject'] = "Verification email" msg['From'] = sender msg['To'] = receiver _session.sendmail(sender, receiver, msg.as_string()) except Exception as e...

Python 접근제한자 public, protected, private

접근제한자는 어떤 클래스의 변수, 인스턴스 변수 , 메서드 사용을 제한한다. python 에는 public, protected, private이 있다. java에는 public, protected, private, default가 있다. public 외부 환경이 클래스의 멤버에 접근 가능하다. (var) protected 자신 클래스 내부 or 상속받은 자식 클래스에서  접근 가능하다. _ 언더바 1개 ( _var ) private 자신 클래스 내부에서만 접근가능하다. __ 언더바 2개 (__var) 파이썬에서 접근제한은 변수나 메서드 이름을 mangling하여 저장함으로서 접근 제한 구현을 하고있기 때문에 엄밀하게 제한이 된 것은 아니며 파이썬 인터프리터에서 접근제한자 오용 오류를 띄우지는 않는다. IDE에 따라 경고 메시지를 띄워주는 경우는 있다. class Student: __homeschool = "j_School" # private class attribute __teacher = "Andrew Drake" # private class attribute def __init__(self, name, age): # instance attribute self.name = name # instance public attribute self.__age = age # instance private attribute # def __ display(self): # private method # print("This is private method") class ChildStudent(Student): __another_school = "b_School" __teacher = "MJ" std = Student("Kim Seung Joo", 20) print(s...

Python len() 함수의 내부 동작 원리

Python에서 객체의 길이를 구할 수 있는 빌트인 함수 len()은 어떻게 작동하는 걸까? 객체의 길이라 하면 표현이 모호하므로 iterable 자료형의 원소 개수가 더 정확하겠다. 대표적인 iterable 자료형으로 List를 예로 들자.   만약 List 객체 a의 원소 개수가 2,500개이고, [0]주소부터 시작해서 [2499]까지 순회하며 count 변수를 1씩 올린다면, len 함수는 O(n)의 시간복잡도를 가진다. Python에서는 len()을 호출할 때마다 객체 내 Item을 반복하면서 돌며 count를 변수를 올리는 형태로 계산하지 않는다. 대신  __len__() 이라는 이름의 매직메서드를 이용하는데, 이 매직 메서드는 length를 attribute로서 사용한다. list는 iterable 데이터 구조의 클래스 안에 정의되어 있으며 __len__ 메서드는 카운터 역할을 한다. list 자료형이 정의거나 저장될 때 자동으로 증가한다.  len을 호출할 때는 순회하며 길이를 찾는 명령어가 아니라 이미 저장되어 있는 len값을 묻는 것과 같다. 따라서, O(1)시간 안에 해결할 수 있다. len함수를 호출했을 때 최악실행시간만 보면 꽤 경제적으로 생각될 수 있으나, 데이터가 정의 될 때 len 값 또한 정의되기 때문에 인터프리터에 부담이 갈 수 있다. 특히 큰 값이 정의될 때 그렇다. ( 단순히 값이 수학적으로 큰 것이 아니라 정보량이 많다는 의미에서 ) 이는 Python 환경에서 Item 개수가 큰 값을 입력받을 때 다른 언어에 비해 느린 요인 중 하나다.

Sphinx로 문서화하고 Gitlab Pages에 배포하기

이미지
파이썬 프로젝트에 좋은 문서화 툴 pip install sphinx sphinx-build . _build 이 글은 https://cpusuite.blogspot.com/2022/08/essentials-pycharm-ide-git.html 의 Pycharm setting essential이라는 글과 '나의 파이썬 프로젝트 초기 세팅법'이라는 제목으로 통합될 예정입니다. GItlab pages를 통해 hosting을 하려면 특별한 룰을 따라야한다. 1번 룰 : 정적 컨텐츠는 반드시 public/  에 위치한다. 2번 룰 :  artifacts 경로를 정의할 것. artifacts with a path to the public/ directory must be defined * artifacts란? Job artifacts란 명세한 Job이 성공했는지, 실패했는지에 대한 파일과 경로의 리스트이다. Job이 수행되면 Job이 어떤 형태로 완료되었는지 정보를 담은 파일을 경로에 저장한다. pages:   stage: deploy   script:     - mv docs/build/html/ public/   artifacts:     paths:     - public   only:   - master For further reference, an example sphinx project for GitLab Pages was pushed around the time you originally posted this question. numpydoc_show_class_members = False gitlab 호스팅을 위한 공식 가이드. image: python:3.7-alpine test: stage: test script: - pip install -U sphinx - sphinx-build -b html ....

Python math 라이브러리, 제곱근

이미지
코딩 테스트 문제를 풀다가 python math 라이브러리의 trunc()를 쓸 일이 생겼다. math 라이브러리의 trunc()와 floor() 모두 인자로 받은 값의 소숫점을 버리는 역할을 한다. floor()는 더 낮은 수로 소숫점을 버리지만, trunc()는 그냥 소숫점 첫째자리부터 끝까지 지워버린다. 오래전에 C로 이런 로직을 과제로서 구현했던 기억이 나지만  Python 상에서는 어떻게 구현이 되어을지 궁금해서 인터넷 검색을 해 보았다. "Python의 math라이브러리의 소스 코드를 열람할 수 있는지." Python은 C의 math함수를 사용한다고 한다. Cpython 구현체의 경우 C의 표준 라이브러리 ( C99 ) Jpython 구현체의 경우 Java의 math 라이브러리를 사용한다. Python의 math는 C 함수의 wrapper이다. 위에서 말한 Python math 라이브러리의 함수들은 표준과도 관련이 있는데, IEEE 754와 관련있다. IEEE 754는 IEEE에서 개발한 컴퓨터에서 부동소수점을 표현하는 가장 널리 쓰이는 표준이다. 제곱근을 구하는 함수를 호출했다고 가정하면 바로 C library로 참조하는 것이 아니라, 제곱근을 구하는 데에 특화된 연산을 하는 이진형태의 파일을 이용한다. 이는 OS안에 배포되어 있으며 많은 마이크로프로세서가 연산에 특화된 명령어를 사용한다고 한다. 컴파일러 또한 기계어로 변환할 때 이를 이용한다고 한다. 사용자의 머신에서 어떤 C 표준 라이브러리의 알고리즘이 쓰일지는 알 수 없지만 쓰일 가능성이 높은 알고리즘들은 다음과 같다고 한다.  https://mathworld.wolfram.com/SquareRootAlgorithms.html https://en.wikipedia.org/wiki/Methods_of_computing_square_roots 컴퓨터로 제곱근을 구하는 알고리즘도 방식이 다양하다는 것을 알 수 있다. 파이썬은 스레드 성능을 유지하기 위하여 동시에 하나의 스레드만 ...

매직 메서드와 빌트인 함수의 차이

<매직 메서드> 프로그래밍 언어에서 사전에 정의해놓은 이름을 가지는 메서드 메서드라는 이름답게, 주로 클래스로부터 생성된 객체가 호출할 수 있는 함수이다. <Python에서의 매직 메서드> 매직 메서드는 순수 파이썬만 이용할 때, 파이썬 라이브러리 또는 프레임워크를 사용할 때, Custom class를 구현할 때 알아두어야하는 개념들이다. 애플리케이션에 따라  매직 메서드들을 오버라이딩하기도하고 필요에 따라 사용하지 않는 경우도 있기 때문에 OOP 설계를 위해서는 파이썬 공식문서의 데이터 모델을 정독해야겠다. <Python에서의 매직 메서드 예시>  매직 메서드의 예시함수들은 다음과 같다. __init__(): 생성자 함수.  인스턴스 초기화 할 때 호출된다. 즉, 객체 생성시 호출된다.  __call__(): 인스턴스가 호출됐을 때 실행. 클래스 안에 이 함수를 쓰면 클래스로부터 생성된 객체를 호출가능하게 만들어준다. __repr__(): 호출하면 객체에 대해 설명하는 텍스트를 주로 리턴한다. custom class의 경우 좋은 포맷을 구현해 놓았다면  디버깅할 때 수월하게할 수 있다. __setattr__(): 속성과 그 대응하는 값을 추가할 때 사용 __hash__(): 빌트인 함수 hash()에 의해 호출되며 integer를 리턴한다. 같은 객체인지의 비교를 위해 사용한다. 사용하고자하는 class가 __eq__() 메서드를 구현하지 않았다면 __hash__() 또한 구현하지 않아야한다. 아래 예시 코드는 public, protected, private 속성, 메서드값을 알아보기 위해 작성한 코드인데 매직 메서드를 설명할 수도 있어서 같은 코드를 사용하였다. 출력값은 해당 객체에 어떤 프로퍼티와 메서드들이 구현되어있는지 리스트 형태로 보여준다. dir() 빌트인 함수를 통해 출력하였다. class Student: __homeschool = "j_School" # priv...

Python 시간차 계산 (datetime, time 모듈)

 datetime 변수안에 datetime.datetime.now()를 지정한 뒤,   datetime.striptime() datetime timedelta time

이 블로그의 인기 게시물

실무진 면접 경험으로 정리하는 백엔드 (1) : 에듀 테크 기업 면접

노마드코더 개발자북클럽 Clean code 완주, 독후감

Blogger 커스터마이징 : CSS 수정 (sticky-header)