누구나 로고
Online CoursesFor BusinessLibraryTrend InsightsFree coursesNoticesContactCareers
모든 강의를 무료로 볼 수 있어요. 회원가입 없이도 학습 가능합니다.
로그인무료 회원가입
강좌파이썬 기초 40강 — 처음 배우는 프로그래밍10강

10강 / 전체 14강

연산자 완전 분석 — 우선순위, 결합성, 연산자 오버로딩 예고

8분 읽기 조회 2

파이썬의 모든 연산자 우선순위와 평가 규칙을 이해하고, 연산자 오버로딩의 원리를 파악한다.

🎯 이 강의에서 배우는 것

파이썬에는 수십 개의 연산자가 있습니다. 이들이 어떤 순서로 평가되는지(우선순위), 같은 우선순위에서 왼쪽부터 평가되는지 오른쪽부터 평가되는지(결합성)를 이해하지 못하면 미묘한 버그가 발생합니다. 이 강의에서는 연산자 우선순위 전체를 체계적으로 정리하고, 증강 할당 연산자와 연산자 오버로딩의 원리까지 이해합니다.

📊 연산자 우선순위 전체 테이블

아래 표에서 위로 갈수록 우선순위가 낮습니다 (나중에 평가됨):

우선순위연산자설명
1 (최저)lambda람다 표현식
2if – else조건 표현식(삼항 연산자)
3or논리 OR
4and논리 AND
5not x논리 NOT
6in, not in, is, is not, <, <=, >, >=, ==, !=비교, 멤버십, 동일성
7|비트 OR
8^비트 XOR
9&비트 AND
10<<, >>비트 시프트
11+, -덧셈, 뺄셈
12*, @, /, //, %곱셈, 나눗셈
13+x, -x, ~x단항 연산자
14**거듭제곱
15 (최고)x[i], x[i:j], x.attr, f()인덱싱, 슬라이싱, 속성, 호출
# 우선순위 실험
print(2 + 3 * 4)        # 14 (곱셈 먼저)
print((2 + 3) * 4)      # 20 (괄호로 우선순위 변경)

print(True or False and False)   # True
# and가 or보다 우선: True or (False and False) = True or False = True

print(not True or True)    # True
# not이 or보다 우선: (not True) or True = False or True = True

print(-2 ** 2)    # -4 (** 먼저, 단항 - 나중)
# ** 가 단항 - 보다 우선: -(2**2) = -4
print((-2) ** 2)  # 4  (괄호로 우선순위 변경)

🔄 결합성 (Associativity)

같은 우선순위의 연산자가 연속으로 나올 때 어느 방향으로 묶을지를 결합성이 결정합니다:

# 왼쪽 결합 (대부분의 연산자)
print(10 - 3 - 2)    # (10-3) - 2 = 5 (왼쪽에서 오른쪽)
print(10 / 2 / 5)    # (10/2) / 5 = 1.0

# 오른쪽 결합 (거듭제곱 ** 와 단항 연산자)
print(2 ** 3 ** 2)   # 2 ** (3**2) = 2**9 = 512 (오른쪽에서 왼쪽!)
print(2 ** (3 ** 2)) # 512 (같은 결과)
print((2 ** 3) ** 2) # 64  (다른 결과)

# 수학에서 a^b^c = a^(b^c)와 동일한 관례
# 할당 연산자도 오른쪽 결합
a = b = c = 5  # c=5, b=5, a=5 순서로 처리

🔗 체인 비교의 정확한 동작

x = 5

# 체인 비교
print(1 < x < 10)    # True — 수학적 표현과 동일
# 내부적으로: (1 < x) and (x < 10)
# 단, x는 한 번만 평가됨

# 함수 호출이 포함된 체인에서 중요
call_count = 0
def get_val():
    global call_count
    call_count += 1
    return 5

call_count = 0
result = 1 < get_val() < 10  # get_val() 한 번만 호출
print(call_count, result)     # 1 True

call_count = 0
result = (1 < get_val()) and (get_val() < 10)  # 두 번 호출
print(call_count, result)     # 2 True

# 다양한 체인 비교
a = b = c = 5
print(a == b == c)    # True
print(a <= b <= c)   # True
print(a != b)         # False

# 주의: 타입이 다르면 예상치 못한 결과
print(0 == False == 0.0)   # True (0 == False 그리고 False == 0.0)

📝 증강 할당 연산자와 가변/불변 차이

+=, -= 등의 증강 할당 연산자는 불변/가변 객체에서 다르게 동작합니다:

# 불변 객체 (int, str, tuple): 새 객체 생성
x = 5
print(id(x))    # 예: 1000
x += 3          # 새 정수 8 객체 생성, x가 가리키는 곳 변경
print(id(x))    # 다른 주소 (새 객체)

# 가변 객체 (list): in-place 수정
lst = [1, 2, 3]
print(id(lst))  # 예: 2000
lst += [4, 5]   # __iadd__ 호출 → 같은 리스트 객체를 수정
print(id(lst))  # 같은 주소! (같은 객체)
print(lst)      # [1, 2, 3, 4, 5]

# 이 차이가 실수로 이어지는 경우
a = [1, 2, 3]
b = a
a += [4, 5]     # a가 가리키는 리스트를 in-place로 수정
print(b)        # [1, 2, 3, 4, 5] — b도 변경됨!

# vs
a = [1, 2, 3]
b = a
a = a + [4, 5]  # 새 리스트 생성 후 a에 할당
print(b)        # [1, 2, 3] — b는 원래 리스트 유지

🎭 연산자 오버로딩 미리보기

파이썬의 연산자는 내부적으로 특수 메서드(dunder method)를 호출합니다. 이것이 1 + 2와 "a" + "b"가 모두 +로 동작하는 이유입니다:

# + 연산자의 내부 동작
a = 1
b = 2
print(a + b)            # 3
print(a.__add__(b))     # 3  (내부적으로 이것을 호출)

s1 = "hello"
s2 = " world"
print(s1 + s2)          # "hello world"
print(s1.__add__(s2))   # "hello world"  (str의 __add__)

# 내장 len()도 특수 메서드 호출
lst = [1, 2, 3]
print(len(lst))         # 3
print(lst.__len__())    # 3  (내부적으로 이것을 호출)

# 모든 연산자 → 특수 메서드 매핑
# +  → __add__ / __radd__
# -  → __sub__
# *  → __mul__
# == → __eq__
# <  → __lt__
# []  → __getitem__
# in  → __contains__
# 커스텀 클래스에서 이 메서드들을 구현하면
# 자신만의 연산자 동작을 정의할 수 있음 (35강에서 자세히 다룸)

💡 괄호 활용 원칙

우선순위를 외우는 것보다 더 중요한 것은 코드 가독성입니다:

# 모호한 코드 (우선순위 암기에 의존)
result = a + b * c ** 2 - d and e or f

# 명확한 코드 (괄호로 의도를 표현)
result = ((a + (b * (c ** 2)) - d) and e) or f

# 실무 원칙:
# 1. 산술 연산과 비교 연산이 섞이면 괄호 사용
# 2. 논리 연산자 and, or, not을 비트 연산자와 섞으면 반드시 괄호
# 3. 확실하지 않으면 괄호를 추가하는 것이 안전

# 불필요한 괄호가 때로는 의도를 명확히 함
if (x > 0) and (y > 0):  # 괄호 없어도 작동하지만 더 읽기 쉬움
    print("1사분면")

⚠️ 자주 하는 실수

  • -2 ** 2가 4가 될 것이라 예상: **가 단항 -보다 우선순위가 높아 -(2**2) = -4입니다. (-2) ** 2 = 4를 원하면 괄호가 필요합니다.
  • and와 &를 혼동: and는 논리 연산자(단락 평가, 원래 값 반환), &는 비트 연산자(항상 두 피연산자 평가, 정수 반환). 불리언에서도 미묘하게 다릅니다.
  • 리스트에서 +=와 +의 차이 모름: lst += [4]는 in-place(공유 참조에 영향), lst = lst + [4]는 새 객체 생성.

📝 정리 및 다음 강의 예고

  • 연산자 우선순위: 산술 > 비교 > 논리 순서 (괄호로 항상 명확히 할 수 있음).
  • 대부분은 왼쪽 결합, 거듭제곱 **만 오른쪽 결합.
  • +=는 불변 객체에서 새 객체 생성, 가변 객체에서 in-place 수정.
  • 파이썬의 모든 연산자는 내부적으로 특수 메서드(dunder)를 호출합니다.

다음 강의: f-string과 모든 문자열 포맷팅 방법을 마스터합니다. % 연산자, str.format(), f-string의 역사와 차이, 그리고 f-string의 모든 형식 지정자를 배웁니다.

관련 주제

  • 연산자 우선순위 테이블
  • 결합성(오른쪽 결합 **)
  • 체인 비교 평가
  • 증강 할당(+=)
  • __iadd__
  • 연산자 오버로딩 개념
  • 개발·프로그래밍
  • 개발·프로그래밍 강의
  • 파이썬 기초 40강 — 처음 배우는 프로그래밍
  • 무료강의
  • 무료 온라인 강의
  • NUGUNA
  • 누구나
이전 9강불리언(bool)과 None — 진리값 시스템의 철학다음 11강 f-string과 문자열 포맷팅 완전 정복

댓글

0/1000

불러오는 중...

목차

  1. 1.컴퓨터는 어떻게 생각하는가 — 0과 1에서 프로그램까지
  2. 2.파이썬 생태계와 개발 환경 완전 설정
  3. 3.파이썬의 실행 모델 — 바이트코드, PVM, GIL
  4. 4.첫 프로그램 — print()와 input()으로 배우는 I/O 원리
  5. 5.변수란 무엇인가 — 이름표, 객체, 참조의 삼각관계
  6. 6.정수(int) 완전 해부 — 임의 정밀도, 비트 연산, 정수 연산의 함정
  7. 7.부동소수점(float)의 함정 — IEEE 754와 수치 오류의 진실
  8. 8.문자열(str) 완전 해부 — 유니코드, 불변성, 인코딩
  9. 9.불리언(bool)과 None — 진리값 시스템의 철학
  10. 10.연산자 완전 분석 — 우선순위, 결합성, 연산자 오버로딩 예고
  11. 11.f-string과 문자열 포맷팅 완전 정복
  12. 12.조건문 — 프로그램이 결정을 내리는 방법
  13. 13.while 루프 — 반복의 본질과 루프 설계
  14. 14.for 루프 — 이터레이션 프로토콜의 깊은 이해

Support

  • Notices
  • FAQ
  • Contact Us
  • Community

Help & Info

  • Terms of Service
  • Privacy Policy
  • Refund Policy

Services

  • About Us
  • Sign up
  • New courses
  • Free courses
누구나 로고
Terms of ServicePrivacy PolicyRefund Policy

상호명: NUGUNA  |  대표자: 정우진  |  사업자등록번호: 392-32-01817  |  통신판매업신고: 제 2026-서울양천-0564 호

주소: 서울특별시 양천구 목동서로 100  |  이메일: nugunapass@gmail.com  |  전화: 010-6395-3043

© 2026 NUGUNA. All rights reserved.

KB예금주인증관리자
HomeCoursesLibraryContactMY