- URL: https://www.youtube.com/watch?v=RHCyTWaRZSk
- 수집일: 2026-10-19
- 채널: ArjanCodes
- 원본 게시일: 2026-10-16 (yt-dlp
upload_date) - 영상 길이: 15분 27초 (yt-dlp 927초)
- yt-dlp 현재 제목: 7 Python Features That Make Your Code Worse
- 요청에 지정된 원제 표기: Popular Python Features You Probably Shouldn’t Use
📌 핵심 질문 / 이 영상이 다루는 핵심 논점
==파이썬 기능은 편리하다는 이유만으로 어디에나 적용하기보다, 코드가 독자에게 만드는 기대와 도메인 경계를 고려해 선택해야 한다.== 이 영상의 일곱 사례는 기능 자체를 금지하는 목록이 아니라, 비용·상태·복잡성을 감춘 채 남용할 때 생기는 설계 위험과 더 명료한 사용 기준을 보여준다.
- 속성처럼 보이는 문법은 값싼 계산을 기대하게 하고, 데코레이터는 함수 본문 밖의 실행 흐름을 가린다.
- 데이터 클래스와 패턴 매칭은 간결하지만, 비즈니스 규칙이 필요한 객체를 무제한 데이터 구조나 불필요하게 복잡한 분기로 만들 수 있다.
- 캐시 만료, 비동기 경계,
slots의 객체 모델 변화는 성능 편의보다 수명·호환성·사용처를 먼저 판단해야 한다.
핵심은 “이 기능을 쓸 수 있는가”가 아니라 “이 코드의 독자가 어떤 동작을 예상하며, 그 선택이 규칙과 복잡성을 어디에 두는가”다. 속성은 속성답게, 데이터 클래스는 데이터 전달에, 캐시는 명시적인 수명 정책과 함께, 데코레이터는 실제 흐름을 가리지 않을 때 사용한다. 비동기 처리는 되도록 인프라 경계에 두고 도메인 로직을 데이터 중심으로 유지한다. slots는 많은 수의 안정된 객체처럼 이점이 분명한 제한된 경우에만 적용한다.
1. 편의 문법이 감춘 비용과 규칙을 드러내기
1.1. (00:00–02:23) 프로퍼티는 속성처럼 예측 가능한 계산에 사용한다
-
속성 문법은 가벼운 접근이라는 기대를 만든다
- 시작 질문은 “이 한 줄의 코드가 어느 정도 일을 한다고 예상하는가?”다.
invoice.total같은 표현은 단순한 필드 읽기처럼 보이므로, 호출자는 계산이 저렴하고 즉각적일 것이라고 기대하기 쉽다. - 문법 자체로 원격 호출을 금지할 수는 없지만, 프로퍼티 안에서 데이터베이스 연결, 여러 API 호출, 네트워크 지연을 감추면 문법이 전달하는 기대와 실제 비용이 어긋난다.
- 시작 질문은 “이 한 줄의 코드가 어느 정도 일을 한다고 예상하는가?”다.
-
송장 총액 사례는 프로퍼티에 숨기기엔 지나치게 많은 일이다
- 가상의 송장 프로퍼티가 DB 연결을 맺고, 송장 데이터를 가져오고, 세율을 조회하고, VAT ID를 검증한 뒤 총액까지 계산한다. 한 번의 속성 접근이 사실상 여러 외부 작업을 수행한다.
- 개발자는 단순한 접근을 기대했다가 지연이나 실패를 맞닥뜨릴 수 있다. 데이터 조회·API 호출·비싼 작업은 일반 메서드로 표현하고, 필요하면
get_접두어로 조회 동작을 드러내며 API 설계에 따라async를 사용해 지연 가능성을 더 명시할 수 있다.
-
프로퍼티는 이미 가진 값으로 하는 속성다운 계산에 적합하다
- 이름과 성을 합쳐 전체 이름을 구하거나, 장바구니 안의 항목 가격 합계를 계산하는 일은 현재 객체가 가진 데이터만으로 수행하는 간단한 계산의 예다.
- 합계 계산도 항목이 수백만 개가 아니라는 전제 아래 “합리적으로 단순한 계산”으로 제시된다. 기준은 프로퍼티라는 문법이 자연스럽게 암시하는 저비용·예측 가능성에 맞는가다.
-
코드 작성법과 소프트웨어 설계는 별개의 판단 능력이다
- Arjan은 설계 기초, 시스템 설계, 아키텍처의 트레이드오프를 파이썬 예제로 다루는
Software Design Mastery프로그램을 짧게 소개하고aron.codes/mastery를 안내한다. - 이 홍보는 기능 선택의 트레이드오프가 단순한 문법 지식이 아니라 설계 판단의 일부라는 영상의 도입 논지와 이어진다.
- Arjan은 설계 기초, 시스템 설계, 아키텍처의 트레이드오프를 파이썬 예제로 다루는
1.2. (02:23–04:23) 데이터 클래스는 데이터 전달에 좋지만 도메인 규칙을 대신하지 않는다
-
데이터 클래스가 주는 실질적 이점
- 상용구 코드를 줄이고 객체를 만들거나 출력하기 쉽게 한다. 클래스 정의만 보아도 객체가 어떤 데이터를 담는지 한눈에 확인할 수 있다는 점도 장점이다.
- 단순한 데이터 구조를 표현하려는 목적에 맞춰 필드가 기본적으로 공개되어 있다. 바로 그 편리함 때문에 값의 유효성을 통제하지 못하는 상황이 생긴다.
-
200% 할인율은 표현할 수 있어도 사업 규칙상 유효하지 않다
items와discount를 가진 쇼핑 카트 데이터 클래스에 200% 할인율을 넣어도 기본 구조만으로는 막을 보장이나 제한이 없다.- 데이터 클래스가 필드를 그대로 노출하는 상태에서 도메인 규칙을 호출자에게 맡기면 잘못된 상태를 만들 수 있다. 객체가 규칙을 소유해야 한다면 그 규칙을 강제하는 연산을 제공해야 한다.
-
일반 클래스로 유효한 연산을 경계로 만든다
- 더 안전한 쇼핑 카트 예시에는 항목 추가와 할인 적용 메서드가 있다. 항목은 가격이 양수일 때만 추가하고 할인율은 0과 1 사이에서만 적용한다.
- 반면 현재 항목의 합계처럼 이미 가진 값만 단순하게 계산하는 프로퍼티는 계속 유용하다. 한 객체 안에서도 필드 변경에는 규칙을 두면서 계산 속성은 프로퍼티로 둘 수 있다.
-
데이터 클래스의 적합한 영역과 작성자의 자기반성
- 설정(configuration), 이벤트(event), 값 객체(value object)처럼 단순한 데이터 표현에는 데이터 클래스가 여전히 훌륭하다. 경계는 “모든 도메인 객체를 데이터 클래스로 만들지 말라”는 데 있다.
- Arjan은 지난 몇 년 동안 자신의 영상에서 데이터 클래스를 과도하게 사용한 경향이 있었다고 인정하고, 농담 섞어 “내 행동 말고 내 말을 따르라”고 말한다.
2. 단순함을 지키고 숨은 실행 흐름을 점검하기
2.1. (04:23–05:32) 패턴 매칭은 구조를 비교할 때 쓰고 단일 조건을 복잡하게 포장하지 않는다
-
패턴 매칭이 빛나는 경우
- 패턴 매칭은 객체의 구조나 여러 속성의 조합을 기준으로 분기해야 할 때 유용하다. 예시에서는 사용자 객체를 대상으로 관리자 여부, 이름 또는 그 조합을 맞춰 결과를 반환한다.
- 구조적 조건이 실제로 중요하거나
can_delete동작이 복잡해질 것으로 예상된다면 패턴 매칭을 택할 이유가 있다. 향후 조건이 더해질 가능성도 설계 맥락의 일부다.
-
is_admin하나만 확인한다면 직접 비교가 더 명료하다- 필요한 것이
is_admin플래그의 참·거짓뿐이라면 패턴을 여러 줄로 표현할 이유가 없다. 단순한 플래그 확인이 복잡한 구조 매칭보다 의도를 직접 드러낸다. - 규칙이 단순할 때는 가능한 한 단순한 해결책을 택하라는 기준이다. 기능의 표현력을 과시하기보다 실제 조건의 구조와 코드의 복잡도를 맞춘다.
- 필요한 것이
2.2. (05:32–06:55) 캐시는 성능 이득과 함께 수명·크기 정책을 설계한다
-
functools.cache는 간단하지만 기본 결과가 만료되지 않는다functools에서cache데코레이터를 가져와 함수에 붙이면 결과를 쉽게 캐싱할 수 있다. 다만 기본 캐시 결과에는 만료 시점이 없다.- 환율처럼 시간이 지나며 바뀌는 값에 적용하면 환율이 변해도 이전 값이 계속 사용될 수 있다. 그 결과 불일치와 오래된 데이터(stale data), 그 밖의 캐시 문제를 낳을 수 있다.
-
TTL과 최대 크기를 요구사항으로 드러낸다
- 캐시의 수명과 한계를 명시하는 대안으로 TTL(Time To Live) 캐시를 소개한다. Arjan이 예시에서 사용하는 패키지는
cachetools다. - 캐시 객체를 만들 때 최대 크기와 TTL 값을 지정하고,
functools.cache와 비슷하게 데코레이터를 사용하되 TTL 캐시 객체를 전달한다. 이렇게 하면 환율 값이 얼마나 오래 유효한지와 언제 갱신할지를 관리할 수 있다.
- 캐시의 수명과 한계를 명시하는 대안으로 TTL(Time To Live) 캐시를 소개한다. Arjan이 예시에서 사용하는 패키지는
-
캐시는 스크립트를 빠르게 할 수 있으나 한계를 알아야 한다
- Arjan은 스크립트에서 캐시가 작업을 상당히 빠르게 할 수 있어 사용하는 것을 좋아한다고 말한다.
- 성능 향상만 보고 적용하지 말고 선택한 캐시의 만료·크기 정책과 그에 따른 오래된 값의 가능성을 분명히 이해하라는 결론이다.
2.3. (06:55–09:05) 데코레이터가 비즈니스 흐름과 순서 결정을 숨기지 않게 한다
-
횡단 관심사는 간결하게 표현할 수 있다
- 파이썬 데코레이터는 로깅이나 프로파일링 같은 횡단 관심사(cross-cutting behavior)를 함수 주변에 간결하게 붙이는 데 유용하다.
- 문제는 하나의 핵심 함수 위에 서로 다른 데코레이터를 많이 겹쳐 적용할 때 시작된다. 예시의
create_account에는 감사(audit), 재시도(retry), 트랜잭션(transactional), 권한 확인(require permission) 등 네 개의 데코레이터가 연결된다.
-
호출 지점만 보아서는 실제 동작을 알기 어렵다
- 함수 본문에는 일부 정보만 있고, 각 데코레이터가 무엇을 하는지는 이름만으로 확정할 수 없다. 호출자는 파이썬이 데코레이터를 함수 래퍼로 처리하고 감싸는 순서에 따라 동작이 어떻게 이어지는지까지 알아야 한다.
- 설명된 래퍼 체인에서는 바깥부터
audit가retry를 호출하고,retry가transactional을 호출하며,transactional이require permission을 호출하고, 권한 래퍼가 원래의create_account를 호출한다. 순서가 결과의 의미를 바꿀 수 있다.
-
데코레이터 순서 자체가 아키텍처 결정이다
- 권한이 없을 때 재시도하는 것이 의미가 있는지, 감사 기록을 항상 남길지 실제 계정 생성 함수가 실행될 때만 남길지 질문이 생긴다. 여러 래퍼가 나열되면 이런 정책이 코드 표면에서 분명하지 않을 수 있다.
- 재시도는 계정을 실수로 여러 번 만들 위험처럼 부작용을 증폭할 수도 있다. 핵심 비즈니스 흐름과 중요한 순서 결정을 “함수 본문이 깔끔해 보이도록” 숨기면 실제 동작을 이해하기 어려워진다.
-
사용 기준은 횡단 관심사를 처리하되 핵심 흐름을 노출하는 것이다
- 로깅 등 공통 관심사에는 데코레이터를 활용할 수 있지만, 각 래퍼가 적용되는 위치와 순서를 호출자가 이해할 수 있어야 한다.
- 여러 데코레이터가 정책과 부작용을 감춘다면 명시적인 함수 호출이나 별도 조합으로 드러내는 편이 낫다. 간결함이 이해 가능성을 희생시키면 이점이 아니다.
3. 인프라 기능을 도메인 경계에 가두고 선택적으로 최적화하기
3.1. (09:05–13:02) 비동기 처리는 되도록 경계에 두고 비즈니스 로직을 독립적으로 유지한다
-
async는 I/O 동시성과 응답성을 제공하지만 전파되기 쉽다- 비동기는 I/O 작업을 동시에 진행하고 애플리케이션이나 스크립트의 반응성을 높이는 유용한 기능이다.
- 비동기 API를 호출하는 함수도 비동기가 되고, 이를 호출하는 함수까지 차례로 비동기화되면서 전체 스크립트에
async가 퍼질 수 있다. Arjan은 비즈니스 로직을 가능한 한 비동기 없는 상태로 유지하려 한다.
-
비동기는 도메인 규칙보다 인프라 관심사에 가깝다
- 사례에는 주문(order), 신용 프로필(credit profile), 프로필을 바탕으로 주문 결정을 내리는 결제 정책(checkout policy)이 등장한다. 신용 프로필 제공자가 비동기 API라면, 프로필을 가져오는 방식 때문에 결제 정책까지 비동기화될 수 있다.
- 데이터 조회 방식과 결정을 내리는 규칙을 분리하면, 도메인 로직은 주문과 프로필을 입력으로 받아 판단하는 역할에 집중할 수 있다.
-
대안 A: 비동기 API를 동기 어댑터 뒤에 감춘다
fetch_profile이 비동기인 신용 API 주변에 차단(blocking) 어댑터를 두고, 도메인 쪽에는 동기get_profile메서드를 제공한다. 예시는asyncio.run으로 비동기 프로필 조회를 실행한다.main함수가 이 래퍼를 사용해 결제 정책에 프로필을 제공하면 정책은 동기식으로 유지된다. 다만asyncio.run은 이미 이벤트 루프 안에서 실행되는 상황에서는 사용할 수 없다는 제약이 있다.
-
대안 B: 애플리케이션 가장자리에서 데이터를 가져와 전달한다
- 다른 설계는 프로필을 가져오는 부분을 도메인 로직과 분리하고, 체크아웃 정책 또는 함수가 주문 정보뿐 아니라 신용 프로필도 인자로 받도록 하는 것이다.
- 이때
main을 비동기로 만들고asyncio.run등으로 호출할 수 있다. 가장자리에서 비동기 제공자를 만들고 프로필을 가져온 뒤, 그 데이터를 동기식 비즈니스 로직에 전달하면 도메인 내부는 비동기 의존성이 없다.
-
두 방식 모두 비동기 경계와 비즈니스 규칙을 구분한다
- 비동기 코드를 도메인 내부에서 다루지 않도록 어댑터로 감싸거나, 외부에서 필요한 데이터를 모두 가져와 인자로 전달할 수 있다.
- 핵심 기준은 애플리케이션 가장자리에서 비동기를 처리하고 내부 로직에는 데이터를 전달하는 것이다. 어댑터는 이벤트 루프 재진입 제약을 고려해야 하므로 모든 상황에 같은 방식으로 적용할 수 있는 해법은 아니다.
3.2. (13:02–15:27) slots는 객체 모델을 바꾸므로 필요성이 입증된 곳에만 적용한다
-
slots=True는 메모리 최적화와 함께 동적 속성을 제한한다- 데이터 클래스와 연관된
slots기능은 예를 들어 x와 y를 가진Point클래스에slots=True를 설정해 파이썬 객체 모델을 변경한다. - 일반 클래스에서 흔한 사후 속성 할당을 할 수 없게 된다.
point.label = ...처럼 원래 선언되지 않은 속성을 추가하면 오류가 발생하며, 일반적인 편집 가능__dict__도 제공되지 않는다.
- 데이터 클래스와 연관된
-
유연한 객체와 슬롯 객체는 사용자가 기대하는 동작이 다르다
slots를 쓰지 않는FlexiblePoint데이터 클래스는 실행 후 새 속성을 붙일 수 있다. 같은 코드를 슬롯 객체에 적용하면 동작 차이가 바로 드러난다.- 이 차이는 단순한 구현 최적화가 아니라 객체를 사용하는 개발자의 기대와 호환성에 영향을 주는 객체 모델의 변화다. 클래스의 공개된 사용처에 이를 무심코 적용하면 놀랄 수 있다.
-
객체 수가 많고 구조가 안정적인 경우에 제한적으로 선택한다
slots는 작고 안정된 객체를 대량으로 만들 때 메모리를 재사용하는 데 도움이 될 수 있다. 하지만 모든 클래스에 자동으로 붙일 기능은 아니다.- Arjan은 속성을 동적으로 추가하지 않을 것을 알고, 많은 객체를 생성해 추가 성능·메모리 이득이 필요한 경우에만 사용한다고 말한다. 특히 서드파티 시스템이 접근하는 곳이 아니라 애플리케이션의 통제된 영역에 적용한다.
-
동적 속성의 설계상 비용도 함께 고려한다
- Arjan은 동적 속성을 계속 붙이는 설계 자체를 대체로 피한다고 말한다.
FlexiblePoint처럼 어떤 데이터가 들어갈지 알 수 없게 되면 타입 정보가 약해질 수 있기 때문이다. - 그는 더 엄격하고 명시적인 구조를 선호한다. 그러므로
slots는 무조건 피할 것도, 기본값처럼 켤 것도 아니며, 동적 확장 가능성과 실제 성능·메모리 필요를 비교해 선택한다.
- Arjan은 동적 속성을 계속 붙이는 설계 자체를 대체로 피한다고 말한다.
주요 발언 모음
“프로퍼티는 속성처럼 동작할 때 사용하라. 데이터를 가져오거나 API를 호출하거나 비용이 큰 작업이라면 메서드로 만들어라.”
“모든 도메인 객체를 데이터 클래스로 만들지는 말라.”
“가능하다면 단순한 해결책을 사용하라. 그것이 훨씬 더 명확한 경우가 많다.”
“캐시를 쓰되, 사용하는 캐시의 한계를 분명히 알아야 한다.”
“데코레이터는 횡단 관심사에 좋지만, 함수 본문을 깔끔하게 보이게 하려고 중요한 비즈니스 흐름을 숨기지 말라.”
“비동기는 가장자리에 두고, 로직 안에서 비동기 코드를 다루지 않도록 어댑터를 쓰거나 데이터를 미리 가져와 전달하라.”
“나는 내 행동 말고 내 말을 따르라.” — 데이터 클래스를 과도하게 사용했던 자신의 사례에 덧붙인 농담
핵심 데이터 & 수치
- 일곱 가지 기능: 프로퍼티, 데이터 클래스, 패턴 매칭, 캐싱, 데코레이터, 비동기 처리,
slots. - 할인율 예시: 데이터 클래스는 200% 할인도 표현할 수 있지만, 안전한 쇼핑 카트는 0~1 범위만 허용한다.
- 데코레이터 예시: 계정 생성 함수에 감사, 재시도, 트랜잭션, 권한 확인의 네 가지 래퍼가 붙어 순서와 부작용을 검토해야 한다.
- 캐시 사례: 환율처럼 변하는 값은 만료 없는 캐시에서 오래된 값이 될 수 있어 TTL과 최대 크기 정책이 필요하다.
- 비동기 경계:
asyncio.run기반 동기 어댑터는 이미 이벤트 루프 안에 있을 때 사용할 수 없다는 제한이 있다. - 슬롯 선택 기준: 속성이 안정된 작은 객체를 많이 만들고 메모리 절약이 중요하며 동적 속성 추가가 필요하지 않은 경우에만 적용한다.
- 영상 메타데이터: ArjanCodes 채널, 원본 게시일 2026-10-16, 길이 927초. yt-dlp 확인 제목은 “7 Python Features That Make Your Code Worse”이며, 작업 요청에 지정된 원제 표기는 “Popular Python Features You Probably Shouldn’t Use”다.
결론 및 시사점
- 기능의 편리함보다 그것이 독자에게 만드는 기대, 도메인 규칙, 실패 가능성, 유지보수 비용을 먼저 평가한다.
- 읽기 문법이 속성처럼 보인다면 값싸고 예측 가능한 계산만 담고, 외부 조회나 지연이 있는 동작은 메서드로 드러낸다.
- 데이터 클래스는 설정·이벤트·값 객체처럼 데이터 중심인 유형에 사용하고, 유효성 규칙이 있는 도메인 객체는 규칙을 강제하는 연산을 제공한다.
- 구조적 조건이 아니라 단일 플래그 하나를 검사한다면 패턴 매칭보다 직접 비교가 명료하다.
- 캐시는 성능 도구인 동시에 일관성 정책이다. 데이터 변동성에 맞춰 TTL과 최대 크기, 갱신 조건을 정한다.
- 데코레이터 체인이 중요한 정책, 순서, 반복 실행 부작용을 가린다면 흐름을 명시적으로 풀어 쓴다.
- 비동기 API의 필요와 도메인의 결정 규칙을 분리하고, 애플리케이션 경계에서 데이터를 전달해 비즈니스 로직을 단순하게 유지한다.
slots의 메모리 이점이 실제로 필요하고 객체 구조가 안정적일 때만 제한적으로 사용하며, 동적 속성 및 외부 사용처와의 호환성을 확인한다.
영상 끝에서 Arjan은 시청자에게 좋아요와 구독을 요청하고, 개발자가 남용하거나 잘못 사용하는 파이썬 기능이 무엇인지, 목록에 동의하지 않는 항목이 있는지 댓글로 의견을 물은 뒤 다음 영상으로 마무리한다. 별도의 실제 질의응답은 없으며, 댓글 토론을 유도하는 질문으로 끝난다.
