
Python
파이썬 · Python 3
은 객체·함수·모듈을 이용해 프로그램을 작성하는 범용 프로그래밍 언어이다. 운영 자동화와 자료 처리에 널리 쓰이며 이름의 바인딩·가변성·예외·실행 환경을 이해하면 짧은 코드가 실제로 바꾸는 상태를 추적할 수 있다.
밑줄 용어에 마우스를 올리거나, 키보드로 선택하거나, 터치하면 설명을 볼 수 있습니다.
로고: Python Software Foundation 공식 자료. 제품 식별을 위해 표시하며 각 상표의 권리는 권리자에게 있습니다.
01무엇이고, 어떤 일을 하나
- 파일·로그·JSON 같은 운영 자료를 읽고 구조화한다.
- 함수·클래스·모듈로 반복 작업과 상태를 구성한다.
- SSH·DB·웹 등의 라이브러리를 연결하여 운영 절차를 자동화한다.
02어떤 순서로 동작하나
- 소스 준비
선택한 실행기와 모듈 환경에서 소스 파일을 읽는다.
- 구문 해석
실행기가 구문을 검사하고 실행할 코드 구조를 준비한다. CPython은 바이트코드 생성·실행 단계를 갖는다.
- 이름·객체 처리
문장이 객체를 만들거나 참조하고 함수 호출·조건·반복에 따라 상태를 바꾼다.
- 결과·실패 처리
계산 결과나 외부 I/O 결과를 사용하고 예외·자원 정리· 종료를 처리한다.
03먼저 알아둘 용어와 구성요소
- b = a는 그 객체를 복제하는 작업이 아니라 같은 객체에 다른 이름을 연결한다.
- ==는 값의 동등성을, is는 동일 객체인지를 비교한다.
- 는 C의 short//long처럼 사용자가 고정 바이트 수를 선택하는 기본 정수형이 아니다.
- str은 텍스트, bytes는 바이트열이고 서로 다른 자료형이다.
- 는 순서가 있는 가변 시퀀스로 서로 다른 타입의 객체를 참조할 수 있다.
- iterable은 iter()로 를 얻을 수 있는 객체이고 는 next()로 값을 하나씩 내다가 끝에서 StopIteration을 알린다.
True·bool·0b1을 값·자료형·표현으로 나누기
같은 객체를 출력·형 조회·2진수 문자열 변환한 결과를 비교하고 표현 길이와 실제 메모리 크기를 구별한다.
실습 구성과 전제
- 의 셀 실행 화면을 기준으로 한다. a에 True를 대입한 뒤 세 함수를 호출한다.
- 실제 수업 화면의 출력과 아래 추가 비교 예제를 구분한다. 2진 문자열의 자릿수로 객체의 저장 크기를 추정하지 않는다.
하나의 값에 서로 다른 질문을 한다
- print(a)는 값을 사람이 읽는 형태로 표시하고 type(a)는 객체의 자료형을 반환한다.
- bin(a)는 정수로 해석 가능한 값을 0b 접두사가 있는 문자열로 표현한다. 객체 자체를 1비트 저장소로 바꾸는 동작이 아니다.
원본 크기로 보기 ↗- a=True 뒤 출력 순서는 True, <class 'bool'>, 0b1이다.
- 입력 객체는 동일하지만 type과 bin의 반환 의미가 다르다.
확인 기준세 출력을 값·형·문자열 표현이라는 열로 나누어 적는다.
수치적 값과 정확한 자료형을 구분한다
- bool은 의 하위 형식이어서 True는 정수 연산에서 1에 대응한다. 그렇다고 type(True)가 로 바뀌지는 않는다.
- isinstance는 상속 관계까지 허용하는 검사이고 type(x) is T는 정확한 형을 비교한다. 용도에 따라 검사 결과가 다를 수 있다.
a = True print(type(a).__name__) print(int(a), bin(a), type(bin(a)).__name__) print(isinstance(a, int), type(a) is int)추가 비교 예제의 출력은 bool / 1 0b1 str / True False다.
확인 기준0b1은 bin의 반환 문자열이고 (a)의 값 1과 형식이 다름을 설명한다.
정수 표현·바이트·문자 인코딩을 나누어 확인한다
- format(1, '08b')는 8자리 문자열을 만들고 .to_bytes는 길이가 정해진 바이트열을 만든다. 같은 숫자의 서로 다른 직렬화 방식이다.
- 문자 '1'을 ASCII 또는 로 인코딩하면 값 0x31인 바이트가 된다. 정수 1을 한 바이트에 넣은 0x01과 같지 않다.
print(format(1, '08b')) print((1).to_bytes(1, 'big').hex()) print('1'.encode('utf-8').hex())각 출력은 00000001, 01, 31이다. 코드의 문자를 메모리 덤프 자체와 혼동하지 않는다.
확인 기준표현을 바꿀 때 입력의 형·출력의 형·길이를 각각 확인한다. 이 출력은 객체의 실제 메모리 점유를 보여 주지 않는다.
실습에서 확인한 동작 원리
- 자료형은 허용되는 연산을, 인코딩은 외부 바이트 표현을 정한다.
- 같은 1이라도 bool 값·정수·2진 문자열·문자 바이트는 다른 대상이다.
얕은 복사의 바깥 목록과 안쪽 목록을 따로 변경하기
객체 복사 뒤 어떤 참조가 분리되고 어떤 참조가 남는지 실제 변경 결과로 추적한다.
실습 구성과 전제
- 두 사진은 서로 다른 중첩 리스트를 사용한 복사 사례다. 하나의 동일 리스트를 이어 조작한 화면이 아니다.
- 의 기본 와 copy 모듈을 대상으로 한다. 아래 재구성 코드는 별도로 실행할 수 있는 작은 예시이며 화면의 객체 주소 숫자를 그대로 재현하지 않는다.
바깥 목록의 항목 교체를 확인한다
- a.copy()는 새 바깥 리스트를 만들고 원소에 대한 참조를 복사한다. a[0]을 100으로 바꾸는 연산은 a의 첫 번째 칸이 가리키는 객체를 교체한다.
- b의 첫 번째 칸은 그대로이므로 바깥 리스트가 독립되었다는 사실을 확인할 수 있다. 이것만으로 중첩 객체까지 모두 복사되었다고 결론내리면 안 된다.
a = [1, 2, [3, 4]] b = a.copy() print(a is b, a[2] is b[2]) # False True a[0] = 100 print(a, b) # [100, 2, [3, 4]] [1, 2, [3, 4]]동일성 비교와 바깥 항목 교체를 분리한 재구성 코드와 예상 출력이다.
원본 크기로 보기 ↗- a=[1,2,[3,4]]에서 b=a.copy()를 만든 뒤 a[0]=100을 수행한다.
- 그 결과 a의 첫 원소만 100으로 바뀌고 b의 첫 원소는 1로 남아 있다.
확인 기준바깥 리스트의 동일성은 a is b로, 안쪽 리스트의 동일성은 a[2] is b[2]로 각각 비교한다.
공유된 안쪽 객체의 변경을 추적한다
- a[2][0]을 바꾸면 먼저 a[2]가 가리키는 내부 리스트를 찾고 그 객체의 첫 칸을 변경한다. b[2]도 같은 내부 리스트를 참조하므로 b로 읽어도 변경이 보인다.
- 이는 b가 a의 모든 변경을 자동으로 따라가는 기능이 아니다. 두 경로가 같은 가변 객체에 도달하기 때문에 나타나는 결과다.
a[2][0] = "Hello" print(a) # [100, 2, ['Hello', 4]] print(b) # [1, 2, ['Hello', 4]]바로 앞 재구성 코드에 이어 실행했을 때의 예상 출력이다.
확인 기준a[2] 자체를 새 리스트로 교체하는 연산과 a[2][0]을 변경하는 연산을 구분한다.
deepcopy는 내부 객체도 대조해서 검증한다
- 두 번째 사진에서는 copy.copy와 deepcopy로 만든 바깥 객체의 id가 다르게 나온다. 바깥 id 세 개만으로 내부 객체가 분리되었다는 사실까지 직접 확인할 수는 없다.
- 기본 중첩 에서는 deepcopy로 내부 도 독립 복제된다. 아래처럼 안쪽 동일성과 변경 후 결과를 비교하면 얕은 복사와 깊은 복사의 차이가 드러난다.
import copy x = [["cat"]] y = copy.copy(x) z = copy.deepcopy(x) x[0].append("lion") print(y, z) # [['cat', 'lion']] [['cat']] print(x[0] is y[0], x[0] is z[0]) # True False별도의 작은 리스트로 재구성한 예시다. 메모리 주소 숫자 대신 동일성과 값 변화를 비교한다.
원본 크기로 보기 ↗- copy.copy(a)와 copy.deepcopy(a)를 각각 b와 c에 대입한다.
- id(a), id(b), id(c)의 출력 값이 모두 다르지만 내부 리스트의 id는 이 사진에서 직접 출력하지 않는다.
확인 기준사용자 정의 객체·외부 자원에는 별도의 복사 의미가 있을 수 있다. 여기의 결과는 기본 예시로 한정한다.
실습에서 확인한 동작 원리
- 얕은 복사는 바깥 컨테이너를 분리하지만 안쪽 가변 객체의 참조는 공유할 수 있다.
- 복사는 id 하나보다 참조 경로와 변경 연산을 함께 추적할 때 정확히 설명된다.
동작·명령 참고 문서
반복 종료를 함수의 입력·반환값으로 재구성하기
range의 종료값, 루프의 break, 함수의 return이 바꾸는 실행 위치를 구분한다.
실습 구성과 전제
- 사진은 range 표현과 카운터 반복의 독립 사례다. 아래 함수는 이 반복을 입력과 반환값이 있는 형태로 재구성한 코드다.
- 에서 실행하는 예시다. 화면에 없는 함수 실행을 실제 촬영 결과로 주장하지 않고 예상 출력을 따로 표시한다.
range의 표현과 실제 반복 값을 구별한다
- range(3)은 0부터 3 미만의 정수를 표현하는 객체다. range 객체를 출력한 문자열과 로 변환한 결과는 다른 표현이다.
- for는 해당 객체를 순회하면서 값을 차례로 받는다. 종료 경계 3이 포함되지 않으므로 이 예시에서 본문을 최대 세 번 수행한다.
원본 크기로 보기 ↗- range(3)을 직접 출력하면 range(0, 3)이 표시된다.
- list(range(3))은 [0, 1, 2]로 출력되어 종료값 3이 제외됨을 보여 준다.
확인 기준종료값을 포함하는 횟수로 계산하지 않는다. 시작·끝·간격과 break 같은 별도 종료 조건을 나누어 읽는다.
카운터 증가와 break의 위치를 추적한다
- 두 번째 사진은 반복에서 카운터를 증가·출력한 뒤 10이면 break한다. range(100)의 모든 값을 쓰지 않고 조건이 만족된 시점에 가장 가까운 루프를 끝낸다.
- 루프 밖의 출력이 이어지므로 break가 프로그램 전체나 함수 전체를 끝내는 명령이 아님을 확인할 수 있다.
원본 크기로 보기 ↗- for range(100) 내부에서 cnt를 1씩 늘리고 cnt==10에서 break한다.
- 화면에는 열 번의 반복 출력 뒤 루프 밖의 탈출 메시지가 보인다.
확인 기준증가·출력·조건 검사 순서가 달라지면 마지막으로 출력되는 값과 수행 횟수가 달라진다.
함수 입력과 반환값으로 결과를 명확히 전달한다
- 재구성 함수는 limit을 받아 그만큼 반복한 뒤 실제 처리 횟수를 반환한다. break는 루프를 끝내고, 뒤의 return은 현재 함수 호출을 끝내며 호출자에게 count를 전달한다.
- 반환값 없이 print만 하는 함수는 호출자가 결과를 계산에 쓰기 어렵다. 출력 효과와 반환값을 분리하면 반복 코드를 자동화 작업에 재사용할 수 있다.
def count_until(limit): if not 1 <= limit <= 100: raise ValueError("limit must be 1..100") count = 0 for _ in range(100): count += 1 if count == limit: break return count result = count_until(10) print(result) # 10정수 limit을 입력하는 학습용 재구성 함수다. 사진의 반복을 함수 경계와 반환값으로 확장했다.
확인 기준예상 결과는 10이다. limit이 허용 범위를 벗어나면 반복을 시작하기 전에 ValueError로 조건 위반을 분리한다.
실습에서 확인한 동작 원리
- range의 끝은 제외되며 반복 중 break가 있으면 전체 수열을 끝까지 소비하지 않을 수 있다.
- break와 return은 이동하는 실행 경계가 다르므로 함수의 입력·상태·출력을 분리해서 추적한다.
동작·명령 참고 문서
장비 클래스로 공통 종류와 개별 주소를 나누기
장비 객체를 생성할 때 생기는 인스턴스 상태와 메서드 호출의 self를 실제 클래스 코드에 연결한다.
실습 구성과 전제
- 사진에는 Server와 Network 클래스, 생성자, 출력 메서드가 함께 있다. 인증 필드는 재구성 코드에서 제거하고 문서용 주소만 사용한다.
- 핵심 구조가 한 화면에 모여 있어 같은 사진을 여러 단계에 중복 배치하지 않는다. 아래 출력은 재구성 코드의 예상 결과다.
클래스 몸체와 생성자의 대입 위치를 구별한다
- 사진의 category는 클래스 수준에 정의되고 __init__은 전달받은 주소를 self.ip에 저장한다. 전자는 종류의 공통 기본값, 후자는 생성한 각 객체의 상태를 표현한다.
- Server(...)를 두 번 호출하면 별도 인스턴스가 생긴다. self는 특정 예약 키워드가 아니라 메서드에서 관례적으로 사용하는 첫 인자 이름이며, bound method 호출 시 인스턴스가 전달된다.
원본 크기로 보기 ↗- Server와 Network에 각각 category와 __init__ 메서드가 정의되어 있다.
- 생성자에서 self.ip를 설정하고 view가 속성을 출력하며, 아래에서 여러 객체를 리스트에 넣는 구성이 보인다.
확인 기준같은 클래스에서 만들었다는 이유로 모든 속성이 하나의 공용 저장소에 들어간다고 해석하지 않는다. 클래스 대입과 self 대입 위치를 대조한다.
두 객체를 만든 뒤 한 객체만 변경한다
- 재구성 코드에서 a와 b의 ip는 각 인스턴스 사전에 저장된다. a.ip를 새 문자열로 바꿔도 b.ip가 자동 변경되지 않는다.
- category는 여기서 불변 문자열을 공통으로 읽는다. 클래스 속성에 가변 를 두고 여러 인스턴스가 그 를 수정하는 경우와 구분한다.
class Server: category = "server" def __init__(self, ip): self.ip = ip def view(self): return f"{self.category}: {self.ip}" a = Server("192.0.2.10") b = Server("192.0.2.11") a.ip = "192.0.2.20" print(a.view()) # server: 192.0.2.20 print(b.view()) # server: 192.0.2.11자격 정보 없이 주소와 종류만 남긴 재구성 예시다.
확인 기준두 인스턴스의 주소 출력이 각각 다르고, a의 변경 뒤 b가 유지되는지 확인한다. 사진의 계정·암호 필드를 복사할 필요는 없다.
bound method와 속성 조회 결과를 연결한다
- a.view()는 a에 묶인 메서드를 호출한다. 이 예시에서는 Server.view(a)와 같은 인스턴스를 전달하므로 동일 문자열을 반환한다.
- vars(a)에는 인스턴스에 설정한 ip가 보이고 category는 클래스 쪽에서 찾는다. a.category를 새로 대입하면 그 인스턴스의 이름이 클래스 기본값을 가릴 수 있다.
print(vars(a)) # {'ip': '192.0.2.20'} print(a.view() == Server.view(a)) # True print(Server.category, b.category) # server server앞의 재구성 객체를 이어 사용한 예상 출력이다.
확인 기준인스턴스 사전에 없는 속성도 클래스에서 조회될 수 있다. vars 출력에 없다는 이유만으로 속성이 존재하지 않는다고 단정하지 않는다.
실습에서 확인한 동작 원리
- 클래스는 공통 속성과 동작을 정의하고, 생성자의 self 대입은 각 인스턴스의 상태를 만든다.
- 메서드 호출은 객체 상태를 인자로 전달하는 구조이므로 데이터와 동작의 연결을 추적할 수 있다.
동작·명령 참고 문서
04예제로 따라가기
- a=[1]; b=a; b.append(2) 뒤에는 a와 b가 같은 리스트 [1,2]를 참조한다.
- print(3)은 화면 출력이고 함수의 return 3은 호출자가 사용할 결과 전달이므로 둘을 바꾸어 쓸 수 없다.
- 로그를 읽어 IP 후보를 추출한 뒤 ipaddress로 검증하면 의 모양 일치와 주소의 실제 유효성을 분리할 수 있다.
05혼동하기 쉬운 점과 확인 기준
- 작은 정수나 문자열의 구현상 재사용 때문에 is가 우연히 참이 되는 결과에 의존하면 안 된다.
- 를 한 번 소진하면 같은 객체에서 다시 처음부터 반복되지 않을 수 있으므로 파일 스트림과 generator를 처럼 재사용한다고 가정하지 않는다.
- .sort()나 append()는 리스트를 변경하고 None을 반환한다. result = items.sort() 이후 result가 None인 현상을 정렬 실패나 빈 리스트로 처리하지 않는다.
06상세 노트 · 실습 자료
헤더 구조, 설정 예시, 수치 계산과 수업 캡처는 아래 노트에서 이어집니다.
공식 문서 · 표준
기초 개념과 동작 설명을 대조한 자료입니다. 제품 버전과 실제 설정에 따른 차이는 본문 및 원문에서 확인하세요.