파이썬의 주요 특징
파이썬은 다음과 같은 다양한 특징과 장점을 가지고 있습니다:
- 읽기 쉬운 문법: 파이썬은 간결하고 읽기 쉬운 문법을 가지고 있어 초보자도 쉽게 배울 수 있습니다. 코드의 가독성이 높아 유지보수가 용이합니다.
- 광범위한 라이브러리: 파이썬은 데이터 분석, 웹 개발, 머신러닝, 과학 계산 등 다양한 분야에 활용할 수 있는 풍부한 라이브러리를 제공합니다. 예를 들어, 데이터 분석에는 pandas, 웹 개발에는 Django, 머신러닝에는 scikit-learn 등이 있습니다.
- 플랫폼 독립성: 파이썬은 운영 체제에 상관없이 동일한 코드를 실행할 수 있습니다. 이는 다양한 환경에서 개발과 배포를 용이하게 합니다.
- 대화형 인터프리터: 파이썬은 대화형 인터프리터를 제공하여, 즉시 결과를 확인하며 개발할 수 있습니다. 이를 통해 빠른 프로토타이핑과 디버깅이 가능합니다.
- 커뮤니티 지원: 파이썬은 전 세계적으로 활발한 개발자 커뮤니티를 가지고 있어, 다양한 자료와 도움을 쉽게 얻을 수 있습니다.
파이썬 설치하기
공식홈페이지에 다운받아 설치합니다.
주의사항:
Add Pyhton 3.6 to PATH (패스경로) 옵션 체크,
경로를 해매지 않으려면 커스텀으로 C:\Python36폴더에 설치하는 것이 편함.
만약 설치가 꼬여서 매번 패스 찾기가 예매하면
시스템 환경 고급에서
환경 변수의 경로를 C:\Python36과C:\Python36\Scripts\를 추가해 주고 재부팅하면 됨.
변수와 값
변수는 저장해 놓는 공간
변수는 숫자가 될 수 없다.
a = b
a = 1
파이썬의 자료형
type(a)
int실수
flot정수
+,-,*,/ 사칙연산
//나누기의 몫
%나누기의 나머지
**제곱
정수, 실수, 변수, 함수,
type(a)
True, Fale, None, Bool
자료형(str문자열)
a = ’hello’
print(a) #자료형을 출력해주는 함수
/n 줄바꿈 /다음에 나오는 문자는 이스케이프 문자로 인식 /n 내림 /t 텝
문자열 인덱싱
문자열을 꺼내옴 ab cde 는 [a][b][_][c][d][e] 문자열의 번호는 > 0,1,2,3,4,5,6 <-의 순서 index라고 한다.
문자열을 잘라오고 [시작:끝] 을 slice
문자열 포멧 변수 format
a= “나는 {1}살 이고 기록이 {0}입니다.”.format(old.s) # 1번{}<old로 2번{}<s로 {위치값}
따라서 {변수}면 들어간다. 출력하면 알아서 나온다.
“{0:=*^30}”.format(”안녕”) # ===============안녕=================
”*15+ ”안녕” + “15” #===============안녕=================
문자열 함수(메서드) #변수=문자열
찾는 함수 변수.find(”012345”) 찾는데 없으면 기본값은 -1
순서 함수 변수,index(”012345”)
변수[변수.rfind(”특정값”):]
찾을때,바꿀때 변수.replace("찾을문자", "바꿀문자", [바꿀횟수])
자르기,매우기 변수.split(”자를변수값”)
대문자함수 변수.upper()
소문자함수 변수.low()
문자열개수&카운터 z= “aaabbc” / z.count(”a”) / a = 3 /
총단위수함수 변수.len(a) / 6
#리스트 list 표기[] 중괄호 설명: 내용가변
#소괄호 tuple 표기() 소괄호 설명: 내용불변
패킹: 패키징하기 #변수선언과 같음.
언패킹: 튜플에서 값을 꺼내오기 #순서를 가져
그밖의 함수
문자 찾기 isalpha()
정수? isdecimal()
10진수? isdigit()
숫의개념? isnumeric()
참고: 함수찾아 보기 dir(str) 함수의 디렉도리(매소드)를 출력해라!
파이썬의 대이터 구조 (0부터 순서~)
대괄호 리스트[] 설명: 내용가변~ list
추가함수 append([추가}) [추가] 객체 그 자체 추가
추가함수. extend([추가]) 추가 변수의 요소 추가
삽입함수 insert(어디에,추가)
삭제함수 del(번쩨:값)
지우기함수 remove(값)
꺼내기함수 pop(꺼내기)
합치기 + 합치기함수 extend #참조: append()를 하면 문자열 자체로 결함
정렬합수 sort() 역정렬함수 revesel()
검출 in 값 in 변수 변수에 값을 확 True & False 로 확인
딕셔너리 dict()
중괄호 딕셔너리{}: key”키”와 value”값”이 쌍으로 하나의 객체(object)를 만든다. 키로 값에 접근
a = {”키”:”값”} #키는 중복 될 수 없으며 값은 변한다. 변수a에 객체를 넣는다.
이러한 객체는 함수del()로 지울수 있고 함수pop()으로 꺼낼 수 도 있다.
객체도 함수를 통해 변수 처럼 사용 한다. update
객체는 “,” 컴마로 이어쓸 수 있고 ⏎으로 내려 사용할 수 있다.
- 변수(Variable): 특정 메모리 주소에 저장된 값을 가리키는 이름표(label) 또는 식별자(identifier)입니다. 새로운 값을 할당하여 변경할 수 있습니다.
- 딕셔너리 값 (Dictionary Value): 딕셔너리 내의 특정 키(key)와 연결된 실제 데이터(예: 숫자, 문자열, 다른 딕셔너리, 리스트 등 Values) 또는 해당 데이터가 저장된 메모리 위치를 가리키는 참조입니다.
딕셔너리의 가져오는 함수들
키 함수 key() 값 함수 values() 객체 함수 items() 없으면 오류 get()은 없어도 넘어간다.
집합의 함수
set() 집합은 중복이 없다. set([]) &교 |합 -차 로 출력 된다.
변수에 추가 .add(값) 업데이트 .updata() 삭제 .del() 하여 사용 된다.
형변환
중복이 되어 있는 변수는 set() 함수를 통해 중복을 제거할 수 있다.
“숫자” = str 형태 int( 숫자)는 정수(Integer) float(숫자)는 실수(Real Number)가 된다.
함수의 성질의 값으로 객체를 변화 시킴 Int() float() type()
int(문자)가 들어가면 “ValueError” 값오류가 나온다.
참고: 신택스에러,
SyntaxError: invalid syntax: 문법:구문 오류
IndentationError: unexpected inden: 들여쓰기 잘못, 탭과 공백이 혼합
💡
파이썬의 코드컨밴션 규칙
(AI에게 코드를 맡긴다고 하면 일관성 유지를 위해 코드컨밴센의 원칙을 프롬프트 해야 함.)
공통 규칙
- 들여쓰기는 공백 4칸을 사용. tab 사용 불가
- 각 줄의 최대 길이는 79자로 제한. 길어질 경우 \ 또는 괄호를 사용하여 다음줄로 나눔
- 모듈 레벨 함수 및 클래스 정의는 두줄 간격으로 작성
- 괄호, 중괄호, 대괄호 내부에는 공백 사용 금지
- 쉼표, 콜론, 세미콜론 앞에 공백 사용 금지. 뒤에는 공백 사용
- 주석은 한 줄의 경우 #을 사용하고 코드와 두칸의 공백을 둠. 여러 줄의 경우 """을 사용
- docstring 작성시 """을 사용
변수 및 함수
- 변수 및 함수명은 영어소문자 및 밑줄(_)로 구성된 snake_case로 작성
- 상수는 영어대문자 및 밑줄(_)로 작성. 모듈 수준에서만 작성.
- 연산자 앞뒤에 공백 사용
- 문자열의 경우 쌍따옴표(")를 사용
- 함수의 docstring은 함수에 대한 설명, args, return에 대한 설명을 포함
- 함수 정의시 typing과 hint를 사용하여 타입 명명
- bool 값 비교시 is 또는 is not을 사용
- 한 줄 조건문은 삼항 연산자를 사용
- 간단한 함수의 경우 lambda 사용
- 글로벌 변수의 경우 모듈내에서만 사용하고 g_로 시작 자료구조
- list와 dict 초기화시 list(), dict() 사용
- set과 tuple 초기화시 set(), tuple() 사용
- 간단한 list의 경우 list comprehension을 사용
클래스
- 클래스명은 CamelCase로 작성
- 클래스 상속시, 상위부모부터 순서대로 작성.
- 클래스내 메서드는 한줄 간격으로 작성.
- 메서드명은 snake_case로 작성
- private의 경우 두 개의 밑줄(__)로 시작
- protected의 경우 한 개의 밑줄(_)로 시작
- 타입 검사시 isinstance()를 사용
- 클래스 변수는 클래스명과 밑줄(_)로 구분
- 클래스 정의시 생성자와 소멸자, str은 필수로 작성 모듈 및 패키지
- 각 패키지 및 모듈은 별도의 줄에 작성
- 표준 라이브러리, 서드 파티 모듈, 로컬 모듈 순서로 작성
- 모듈명은 영어 소문자로 작성
파일 입출력
- 파일을 열 때는 with을 사용하여 자동으로 닫히도록 함.
- 로그 작성시 날짜와 시간은 반드시 포함할 것.
조건문 :
if 일때 조건 변수==(! =)값 : 같으면 다음으로
> = 이상
< 이전
and 그리고
and not 그렇지않고
or 또는
elif 조건 그렇지 않고
else: 위 전부 아니라면 다음으로
score = int(input("점수를 입력하세요 (0~100): "))
attendance = float(input("출석률을 입력하세요 (0~100): "))
# 1. 기본 범위 체크 (비교 연산자, 논리 연산자)
if score < 0 or score > 100 or attendance < 0 or attendance > 100:
print("입력 값이 유효 범위를 벗어났습니다.")
else:
# 2. 중첩 if: 과락(40점 미만) 먼저 체크
if score < 40:
print("결과: 불합격 (과락)")
else:
# 3. 다중 조건 if-elif-else로 등급 산정
if score >= 90 and attendance >= 80:
grade = "A"
elif score >= 80 and attendance >= 75:
grade = "B"
elif score >= 70 and attendance >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
# 4. 추가 조건: 우수/경고 태그 부여 (중첩 if, not, 비교 연산자)
tag = ""
if grade in ("A", "B") and attendance >= 90:
tag = " (우수)"
elif grade == "D" and not (attendance >= 70):
tag = " (출석 경고)"
print(f"점수: {score}, 출석률: {attendance}%")
print(f"최종 등급: {grade}{tag}")
반복문 while :
while 조건에 맞을 때 까지 반복
guest = 1
while guest < 10:
print("손님이 {} 명 입니다.".format(guest))
guest = guest + 1
if guest == 10:
print("손님이 꽉 찼습니다.")
num = 1
while num <= 10:
if num % 2 == 0:
print("짝 {}".format(num))
else:
print("홀 {}".format(num))
num = num + 1
num = 1
hap = 0
while num <= 100:
hap += num
num += 1
print(hap)
반복문 for :
for 순차적인 요소가 있을 경우
요소함수 enumerate(요소[,start=])
a = "abcdef"
for i in a:
print(i)
# range()는 차순반복함수 +(더하면서)를 하면서 (1, 10, 2) 1부터 10까지 2씩 넘어가기의 의미
for i in range(1,5+1):
print(1)
student = [{"홍길동": 100}, {"가체즈": 200}, {"가가멜": 300}]
for s, i in enumerater(student, start=1):
data = (list(i.items())[0])
name = data[0]
value = data[1]
print("{} 이름: {} 점수: {}".format(s, name, value))
result = []
for num in range(1, 6):
result.append(num + 5)
print(result)
result = [num + 5 for num in range(1, 6)]
print(result)
result = [num * 3 for num in range(1, 99) if num % 2 == 0] # 묶어쓰기
for num in range(1, 99): #풀어쓰기
if num % 2 == 0:
result.append(num * 3)
for i in range(2, 10):
for j in range(1, 10):
result = i * j
gugudan = ("{} X {} = {}".format(i, j, result))
print(gugudan)
# gugudan = [i * j for i in range(2, 10) for j in range(1, 10)]
# print(gugudan)
묶어쓰기와 풀어쓰기를 자유자제로 쓸 수 있도록 반복 훈련 중요
cotinue 걸려저서 나온 것에 반복
for i in range(1, 100):
if i % 2 == 0:
continue
hap += i
print("홀수의 합 {}".format(hap))
break 조건에 걸리면 정지
num = 0
for i in range(1, 100):
for j in range(100):
print(i,j)
if j == 10:
break
사용자 입력 받기
user = input("사용자 이름을 입력하세요.>")
print(user)
num1 = int(input("숫자1"))
num2 = int(input("숫자2"))
print(num1 + num2)
langs = ["한국어", "English"]
for i, 1 in enumerate(langs, starts=1):
print("{}. {}".format(i, 1))
while True:
sel = input("언어를 선택하세요.>"
if not sel.isnumeric():
continue
sel = int(sel)
if 0 < sel < 3:
break
print("사용자가 선택한 언어는 {} 입니다.".format(langs[sel-1]))
파일 읽고 쓰기
내장함수 100선
| No. | Category | Function | Description | Example Code # 결과값 |
|---|---|---|---|---|
| 1 | Type Conversion | abs() | 절대값 반환 | print(abs(-5)) # 5 |
| 2 | Type Conversion | int() | 정수형으로 변환 | x = int('42'); print(x) # 42 |
| 3 | Type Conversion | float() | 부동소수점으로 변환 | y = float('3.14'); print(y) # 3.14 |
| 4 | Type Conversion | str() | 문자열로 변환 | s = str(123); print(s) # '123' |
| 5 | Type Conversion | bool() | 부울값으로 변환 | b = bool(1); print(b) # True |
| 6 | Type Conversion | list() | 리스트로 변환 | lst = list('abc'); print(lst) # ['a', 'b', 'c'] |
| 7 | Type Conversion | tuple() | 튜플로 변환 | tpl = tuple([1, 2]); print(tpl) # (1, 2) |
| 8 | Type Conversion | dict() | 딕셔너리로 변환 | d = dict([('a', 1)]); print(d) # {'a': 1} |
| 9 | Type Conversion | set() | 집합으로 변환 | s = set([1, 2, 2]); print(s) # {1, 2} |
| 10 | Type Conversion | complex() | 복소수로 변환 | c = complex(1, 2); print(c) # (1+2j) |
| 11 | Type Check | type() | 객체의 타입 반환 | print(type(42)) # |
| 12 | Type Check | isinstance() | 객체가 특정 타입인지 확인 | print(isinstance(42, int)) # True |
| 13 | Type Check | callable() | 객체가 호출 가능한지 확인 | print(callable(print)) # True |
| 14 | Sequence | len() | 시퀀스 길이 반환 | print(len([1, 2, 3])) # 3 |
| 15 | Sequence | max() | 최댓값 반환 | print(max([3, 1, 2])) # 3 |
| 16 | Sequence | min() | 최솟값 반환 | print(min([3, 1, 2])) # 1 |
| 17 | Sequence | sum() | 요소의 합 반환 | print(sum([1, 2, 3])) # 6 |
| 18 | Sequence | sorted() | 정렬된 리스트 반환 | print(sorted([3, 1, 2])) # [1, 2, 3] |
| 19 | Sequence | reversed() | 역순 이터레이터 반환 | list(reversed([1, 2, 3])) # [3, 2, 1] |
| 20 | Sequence | enumerate() | 인덱스와 값 반환 | for i, v in enumerate(['a']): print(i, v) # 0 a |
| 21 | Sequence | zip() | 여러 시퀀스 묶음 | list(zip([1, 2], ['a', 'b'])) # [(1, 'a'), (2, 'b')] |
| 22 | Iterator | iter() | 이터레이터 객체 반환 | it = iter([1, 2]); next(it) # 1 |
| 23 | Iterator | next() | 이터레이터의 다음 요소 반환 | it = iter([1, 2]); print(next(it)) # 1 |
| 24 | Functional | map() | 함수를 시퀀스에 적용 | list(map(str, [1, 2])) # ['1', '2'] |
| 25 | Functional | filter() | 조건에 맞는 요소 필터링 | list(filter(lambda x: x > 1, [1, 2])) # [2] |
| 26 | Functional | reduce() | 누적 함수 적용 (functools) | reduce(lambda x, y: x+y, [1, 2, 3]) # 6 |
| 27 | Functional | lambda | 익명 함수 정의 | f = lambda x: x*2; print(f(5)) # 10 |
| 28 | Functional | all() | 모든 요소가 참인지 확인 | print(all([True, True])) # True |
| 29 | Functional | any() | 하나 이상 참인지 확인 | print(any([False, True])) # True |
| 30 | String | ord() | 문자의 유니코드 값 반환 | print(ord('A')) # 65 |
| 31 | String | chr() | 유니코드 값의 문자 반환 | print(chr(65)) # 'A' |
| 32 | String | format() | 문자열 포맷팅 | '{} {}'.format('Hello', 'World') # 'Hello World' |
| 33 | String | repr() | 객체의 문자열 표현 반환 | print(repr('hello')) # "'hello'" |
| 34 | String | ascii() | ASCII 표현 반환 | print(ascii('café')) # "'caf\xe9'" |
| 35 | Numeric | pow() | 거듭제곱 계산 | print(pow(2, 3)) # 8 |
| 36 | Numeric | round() | 숫자 반올림 | print(round(3.7)) # 4 |
| 37 | Numeric | divmod() | 몫과 나머지 반환 | print(divmod(10, 3)) # (3, 1) |
| 38 | Numeric | hex() | 16진수 문자열 반환 | print(hex(255)) # '0xff' |
| 39 | Numeric | oct() | 8진수 문자열 반환 | print(oct(8)) # '0o10' |
| 40 | Numeric | bin() | 2진수 문자열 반환 | print(bin(8)) # '0b1000' |
| 41 | Dictionary | dict.get() | 키 값 반환 (기본값 지정 가능) | d = {'a': 1}; print(d.get('b', 0)) # 0 |
| 42 | Dictionary | dict.keys() | 모든 키 반환 | d = {'a': 1}; list(d.keys()) # ['a'] |
| 43 | Dictionary | dict.values() | 모든 값 반환 | d = {'a': 1}; list(d.values()) # [1] |
| 44 | Dictionary | dict.items() | 키-값 쌍 반환 | d = {'a': 1}; list(d.items()) # [('a', 1)] |
| 45 | Dictionary | dict.pop() | 키 제거 및 값 반환 | d = {'a': 1}; d.pop('a') # 1 |
| 46 | Dictionary | dict.update() | 딕셔너리 업데이트 | d = {'a': 1}; d.update({'b': 2}) # {'a': 1, 'b': 2} |
| 47 | List | list.append() | 리스트 끝에 요소 추가 | lst = [1]; lst.append(2) # [1, 2] |
| 48 | List | list.extend() | 리스트 확장 | lst = [1]; lst.extend([2, 3]) # [1, 2, 3] |
| 49 | List | list.insert() | 특정 위치에 요소 삽입 | lst = [1, 3]; lst.insert(1, 2) # [1, 2, 3] |
| 50 | List | list.remove() | 첫 번째 일치 요소 제거 | lst = [1, 2]; lst.remove(1) # [2] |
| 51 | List | list.pop() | 인덱스 요소 제거 및 반환 | lst = [1, 2]; lst.pop(0) # 1 |
| 52 | List | list.clear() | 모든 요소 제거 | lst = [1, 2]; lst.clear() # [] |
| 53 | List | list.index() | 요소의 인덱스 반환 | lst = [1, 2]; lst.index(2) # 1 |
| 54 | List | list.count() | 요소의 개수 반환 | lst = [1, 1, 2]; lst.count(1) # 2 |
| 55 | List | list.sort() | 리스트 정렬 | lst = [3, 1]; lst.sort() # [1, 3] |
| 56 | List | list.reverse() | 리스트 역순 | lst = [1, 2]; lst.reverse() # [2, 1] |
| 57 | String | str.split() | 문자열 분할 | s = 'a,b'; s.split(',') # ['a', 'b'] |
| 58 | String | str.join() | 문자열 결합 | ''.join(['a', 'b']) # 'ab' |
| 59 | String | str.strip() | 양쪽 공백 제거 | ' hello '.strip() # 'hello' |
| 60 | String | str.replace() | 문자열 대체 | 'hello'.replace('h', 'H') # 'Hello' |
| 61 | String | str.upper() | 대문자로 변환 | 'hello'.upper() # 'HELLO' |
| 62 | String | str.lower() | 소문자로 변환 | 'HELLO'.lower() # 'hello' |
| 63 | String | str.find() | 부분 문자열 위치 반환 | 'hello'.find('ll') # 2 |
| 64 | String | str.startswith() | 문자열로 시작하는지 확인 | 'hello'.startswith('he') # True |
| 65 | String | str.endswith() | 문자열로 끝나는지 확인 | 'hello'.endswith('lo') # True |
| 66 | String | str.isdigit() | 모두 숫자인지 확인 | '123'.isdigit() # True |
| 67 | String | str.isalpha() | 모두 문자인지 확인 | 'abc'.isalpha() # True |
| 68 | String | str.isalnum() | 모두 문자 또는 숫자인지 확인 | 'abc123'.isalnum() # True |
| 69 | String | str.isspace() | 모두 공백인지 확인 | ' '.isspace() # True |
| 70 | Input/Output | print() | 화면에 출력 | print('Hello', 'World') # Hello World |
| 71 | Input/Output | input() | 사용자 입력 받음 | name = input('Name: ') # 사용자 입력 저장 |
| 72 | Input/Output | open() | 파일 열기 | f = open('file.txt'); f.close() # 파일 열고 닫기 |
| 73 | Input/Output | format() | 문자열 포맷팅 | f'{x:.2f}' # 소수점 2자리로 표현 |
| 74 | Memory | id() | 객체의 메모리 주소 반환 | print(id([1])) # 메모리 주소 |
| 75 | Memory | hash() | 객체의 해시값 반환 | hash((1, 2)) # 해시값 |
| 76 | Memory | dir() | 객체의 속성 및 메서드 나열 | dir(list) # 리스트의 메서드 리스트 |
| 77 | Memory | vars() | 객체의 dict 반환 | vars(obj) # 객체의 속성 딕셔너리 |
| 78 | Memory | globals() | 전역 심볼 테이블 반환 | print(globals()['name']) # 'main' |
| 79 | Memory | locals() | 지역 심볼 테이블 반환 | def f(): print(locals()) # 지역 변수 딕셔너리 |
| 80 | Iteration | range() | 숫자 시퀀스 반환 | list(range(3)) # [0, 1, 2] |
| 81 | Iteration | slice() | 슬라이스 객체 생성 | s = slice(1, 3); [0, 1, 2][s] # [1, 2] |
| 82 | Object | getattr() | 객체 속성값 반환 | getattr(obj, 'attr', None) # 속성값 |
| 83 | Object | setattr() | 객체 속성값 설정 | setattr(obj, 'attr', value) # 속성 설정 |
| 84 | Object | hasattr() | 객체가 속성을 가지는지 확인 | hasattr(obj, 'attr') # True/False |
| 85 | Object | delattr() | 객체 속성 삭제 | delattr(obj, 'attr') # 속성 삭제 |
| 86 | Object | object | 모든 클래스의 기본 클래스 | class MyClass(object): pass # 객체 상속 |
| 87 | Class | super() | 부모 클래스 메서드 호출 | super().init() # 부모 클래스 초기화 |
| 88 | Class | classmethod | 클래스 메서드 데코레이터 | @classmethod def method(cls): pass |
| 89 | Class | staticmethod | 정적 메서드 데코레이터 | @staticmethod def method(): pass |
| 90 | Class | property | 속성 데코레이터 | @property def attr(self): return self._attr |
| 91 | Execution | exec() | 파이썬 코드 실행 | exec('x = 1 + 1'); print(x) # 2 |
| 92 | Execution | eval() | 표현식 계산 | eval('2 + 2') # 4 |
| 93 | Execution | compile() | 파이썬 코드 컴파일 | code = compile('x=1', '', 'exec') |
| 94 | Module | import | 모듈 임포트 | import math; print(math.pi) # 3.14159... |
| 95 | Module | import | 모듈 동적 임포트 | mod = import('math') # 모듈 로드 |
| 96 | Control | exit() | 프로그램 종료 | exit() # 프로그램 종료 |
| 97 | Control | quit() | 인터프리터 종료 | quit() # 대화형 모드 종료 |
사용자 함수
기초지식
매개변수(파라메타, 파람, 인지값): 함수에 인뭇 데이터를 전달하기 위한 변수
지역변수 = 개인 사물함
전역변수 = 공용 사물함
집에서 방마다 사물함이 있다고 상상해 보자. 지역변수는 각 방(함수) 안의 개인 사물함처럼 그 방에서만 쓸 수 있고, 방을 나가면 사라진다. 반대로 전역변수는 집 전체(프로그램)의 공용 사물함처럼 어느 방에서도 쓸 수 있고, 집이 문 닫힐 때까지 남아 있다.
# 전역변수: 집 전체에서 공유 (공용 사물함)
# 이 코드에서 money(global variable)는 함수 밖에서 선언되어 모든 함수에서 접근 가능하며,
# data segment에 저장되어 프로그램 lifetime 동안 지속된다.
# 반면 candy_price, toy_price(local variables)는 함수 블록 내에서만 유효하며,
# 함수 종료 시 stack에서 자동 해제된다.
money = 1000 # 프로그램 시작 시 생성, 종료까지 유지
def eat_candy(): # 방1: 사탕 사먹기
candy_price = 200 # 지역변수: 이 방에서만 (개인 사물함)
money -= candy_price # 공용 사물함에서 돈 빼기
print(f"사탕 사먹고 돈 남음: {money}원") # 800원 출력
def buy_toy(): # 방2: 장난감 사기
toy_price = 500 # 지역변수: 이 방에서만 (다른 방에선 못 봄)
print(f"장난감 가격: {toy_price}원") # 500원 출력
# candy_price는 여기서 못 씀! (NameError 발생)
eat_candy() # 800원 출력
buy_toy() # 500원 출력
print(f"최종 돈: {money}원") # 800원 출력 (전역변수 유지)
| 구분 | 지역변수 (Local) | 전역변수 (Global) |
|---|---|---|
| 선언 위치 | 함수/블록 내부 | 함수 외부 |
| 접근 범위 | 선언된 블록 내 한정 | 프로그램 전체 |
| 수명 | 블록 종료 시 소멸 | 프로그램 종료 시 소멸 |
| 메모리 | Stack (빠름) | Data segment |
| Best Practice | 우선 사용 (모듈화 ↑) | 최소화 (버그 위험 ↓) |
****지역변수를 전역변수로 불러 오는 함수 global 변수
def get_input_user(msg, casting=int):
while True:
try:
user_input = input(msg)
# 이름 입력일 때, 빈 문자열이면 안내 후 다시 입력
if casting is str and not user_inputstrs.strip():
print("이름이 입력되지 않았습니다.")
continue
user = casting(user_input)
return user
except:
continue
user = get_input_user("사용자 이름을 입력하세요> ", str)
age = get_input_user("사용자 나이를 입렵하세요> ") # 1.casting=int (,int)생략
print(user, age)
뮤테이블(콜바이레퍼런스) List Dictionay
독스트링
포지셔널 아규먼트
키워드 아큐먼트
def get_input_user(msg, casting):
'''독스트린: 리드미 사용자에게 msg를 출력하고 casting 형태를 확인하여 입력된 값을 리턴합니다.
파이썬에서 독스트링(docstring)과 주석(comment)은 코드 가독성과 문서화를 위한 도구지만, 문법, 접근성, 용도에서 명확한 차이를 보인다.
Args:
msg (str) : input 시 출력할 문구
castring (class) : 사용자에게 입력 받은 값
'''
while True:
try:
user_input = input(msg)
# 공백만 입력했을 때는 다시 입력 요구
if casting is str and not user_input.strip():
print("이름이 입력되지 않았습니다.")
continue
return casting(user_input)
except:
# 형 변환 실패하면 다시 입력
print("잘못된 입력입니다. 다시 입력하세요.")
continue
def is_prime_number(num):
prime_lists = [False, False] + [True] * (num - 1)
primes = []
for i in range(2, num + 1):
if prime_lists[i]:
for j in range(2 * i, num + 1, i):
prime_lists[j] = False
primes = [i for i in range(2, num + 1) if prime_lists[i] == True]
if num in primes:
return True
else:
return False
# 함수 밖에서 입력 및 출력 처리
num = get_input_user("2 이상의 숫자를 입력하세요> ", int)
if is_prime_number(num):
print("{} 는 소수 입니다.".format(num))
else:
print("{} 는 소수가 아닙니다. ".format(num))
def save_winner(*args): #튜플/ *args포지셔널 아규먼트 들어간 순서를 지켜 준다. *하나
print(args)
def save_winner2(**kwargs): # **kwargs 키워드 아규먼트 이름을 키를 주고 값을 같이 넘긴다. **둘
print(kwargs)
if kwrgs.get("name1"):
print(kwargs["name1"]) #파이썬의 함수의 특징은 일급객체라고 하는데 함수를 변수의 닮을 수 있는 것이 특징
save_winner("홍길동")
save_winner("홍길동", "가가멜")
save_winner("홍길동", "가가멜", "아즈라엘")
save_winner2(namel1="홍길동", name2="가가멜")
def hi():
print("Hello")
hello = hi #
hello() # hi함수는 ()로 닮을 수 있는 반면 hello라는 변수를 만들어서 hi를 직관적으로 닮을 수 있다.
print(type(hello)) # 오호~~~ 신기함. 진관적이라 이해가 좀 안감. 일단 암기
##함수 안네 함수 넣기
def outer_function(func):
def inner_function(**args, **kwargs): #만약 어떤 인자가 넘어 올지 모르는 상황이면~
print("함수명: )
클로저 기술 일급 함수에 네임바인딩 기술?
파이썬 함수의 특징
(언젠가는 써먹는다 & 누군가(실력자)의 코드를 보고 대충 파악하려면 대충 알고 넘어가자~!)
파이썬에서 클로저는 “함수 + 그 함수가 기억해야 할 변수들(환경)을 한 덩어리로 묶어 둔 것”이고, 일급 함수는 “함수를 숫자처럼 변수에 넣고, 다른 함수에 주고, 다시 돌려줄 수 있는 것”을 말한다. 이름 바인딩(name binding)은 “이름(변수)이 실제 값(객체)을 가리키도록 연결하는 것”이고, 클로저는 그 연결을 함수 안에 꼭 붙들고 있는 기술이라고 보면 된다.
1. 일급 함수: 함수도 ‘장난감’이다
초등학생 비유로 설명해 보자.
- “숫자”는 장난감처럼 상자에 넣을 수 있다 →
x = 10 - 파이썬에서는 “함수”도 장난감처럼 상자에 넣을 수 있다 →
f = hello
def hello(name):
return "안녕, " + name
# 1) 함수 이름을 변수에 넣기 (이름 바인딩)
h = hello # h라는 이름이 hello 함수를 가리킴
print(h("민수")) # "안녕, 민수"
- 여기서
h = hello는 “h라는 이름을hello라는 함수 객체에 바인딩한다(이름을 붙인다)”는 뜻이다. - 함수가 숫자처럼 변수에 들어가고, 다른 함수에 넘겨질 수 있으니까 “일급 함수(first-class function)”라고 부른다.
2. 클로저: 기억을 가진 함수
이제 “기억하는 함수” 예제를 보자.
pythondef make_adder(x): # x를 기억시키고 싶은 바깥 함수
def adder(y): # 안쪽 함수(클로저가 될 후보)
return x + y # 바깥의 x를 사용
return adder # 안쪽 함수를 그대로 돌려줌
add_5 = make_adder(5) # x = 5를 기억하는 adder를 하나 만듦
add_10 = make_adder(10) # x = 10을 기억하는 adder를 또 만듦
print(add_5(3)) # 5 + 3 = 8
print(add_10(3)) # 10 + 3 = 13
-
make_adder(5)를 호출할 때x라는 이름은 값5에 바인딩된다. - 파이썬은
adder함수 객체 안에 “x라는 이름은 5를 가리켜야 해”라는 정보를 같이 저장해 둔다. - 이렇게 바깥 함수가 끝난 뒤에도, 안쪽 함수가 바깥 변수에 대한 이름 바인딩을 “기억”하는 것이 클로저다.
초등학생 버전 비유:
-
make_adder= “숫자를 기억하는 로봇을 만드는 공장” -
add_5= “5라는 숫자를 기억하는 로봇” -
add_10= “10이라는 숫자를 기억하는 로봇” - 로봇 안에는 “내가 기억한 숫자” 칸이 있고, 이 칸을 통해 계속 계산을 한다 → 이 “내부 기억 칸”이 바로 클로저의 환경(environment)이다.
3. 이름 바인딩 기술: 클로저 안에서 어떻게 기억하나?
조금 더 “엔지니어 시점”으로 보면:
- 클로저는 “렉시컬 스코프 기반 name binding을 유지하는 레코드(환경) + 함수 코드”이다.
- 파이썬 함수 객체에는
__closure__라는 속성이 있고, 여기에 캡처된 변수들이 cell 객체 형태로 저장된다.
간단히 내부 구조를 엿보는 예:
pythondef outer():
msg = "hello" # 이 변수를 클로저가 캡처
def inner():
return msg # 바깥 변수 사용
return inner
fn = outer() # 클로저 생성
print(fn()) # "hello"
print(fn.__closure__[0].cell_contents) # "hello" 를 내부에서 들고 있음
-
msg라는 이름이 가리키는 실제 객체에 대한 참조가__closure__안의 cell에 저장되어 있어서,outer가 끝나도 GC로 날아가지 않고 계속 살아 있다. - 이 구조 덕분에 “클로저 = 함수가 만들어질 때의 이름 바인딩(환경)을 함께 싸서 들고 다니는 객체”로 동작한다.
4. 한 줄 정의들
- 일급 함수: “함수도 숫자처럼 상자(변수)에 넣고, 친구한테 건네줄 수 있는 언어의 기능”이다.
- 이름 바인딩: “이름표(변수)를 어떤 진짜 물건(값, 함수)에 붙여 주는 것”이다.
- 클로저: “밖에서 가져온 값을 기억한 채로 계속 써 먹는 똑똑한 함수”이고, 이때 기억을 유지하는 방식이 바로 ‘렉시컬 스코프 기반 이름 바인딩을 저장하는 레코드(환경)를 함수와 같이 들고 다니는 것’이다.
원하면, 위 예제를 가지고 “파이썬 Tutor 스타일”로 호출 스택/환경 그림을 같이 그려 주면서 더 포멀하게 정리해 줄 수 있다
Top comments (0)