이것저것 라이브러리와 소스를 갖다 써서 프로젝트는 완성했는데, 정작 기본 문법이나 자료형을 아직도 잘 모르겠다. 그래서 공부하는 김에 간단히 정리해서 올려보겠다.
이번 게시물에서는 기본 자료형(Built-in Types)에 대해 간략하게 알아보겠다. (3.8 버전 기준)
Python documentation은 이 링크에서 확인할 수 있다.
기본 자료형(Built-in Types)의 종류
- 0. 내장 상수
- 1. 숫자 (numerics)
- 2. 시퀀스 (sequences)
- 3. 매핑 (mappings)
- 4. 예외 (exceptions)
0. 내장 상수
내장 상수가 여러개 있다. 그 중 자주 쓰는걸 소개하면 아래와 같다. (나머지는 여기)
- bool 클래스
: 후술할int
클래스의 subclass
- True
- False
- None:
NoneType
클래스의 유일한 값
이 상수에 뭔가 다른 값을 덧씌울 수 없다. 덧씌울 경우 SyntaxError
를 raise 하게 된다.
1. 숫자 (numerics)
a = 1 + 2
b = 4 + 5.6
c = 7 + 8j
print(a) # 3
print(type(a)) # <class 'int'>
print(b) # 9.6
print(type(b)) # <class 'float'>
print(c) # (7+8j)
print(type(c)) # <class 'complex'>
- 정수 (int)
- 실수 (float)
- 복소수 (complex)
먼저 정수의 표현범위가 무제한이다. 파이썬 2에서는 정수값 범위에 따라 int
, long
여부가 결정되었는데 3은 상관이 없다. 실수는 C의 double
과 비슷하다.
복소수는 숫자 뒤에 리터럴 j
를 붙이면 된다. 대문자 J
도 된다.
\[a = 1+8j ~~ (i 아님)\]
예를 들어 a = 1 + 8j 라고 쓰면 a는 실수부가 1이고 허수부가 8인 1 + 8i가 되는 셈이다.
그런데 문득 궁금해졌다. 왜 i가 아니고 j일까?
파이썬 창시자의 말로는 'i랑 I, 1이랑 헷갈리지 않느냐', 'V=IR 이런 식으로 공학에서 I를 쓰니까 헷갈리지 않게 j를 쓴거다' 이런식으로 이유를 들었다.
그런데 stackoverflow의 한 유저가 댓글에서 지적했다시피 소문자 i를 써도 무방했을 것 같다. J는 줄(N*m)이기도 하고.
어쨌거나 파이썬 개발자가 바꿀 일 없다니까 파이썬 복소수에서는 j를 쓴다는 걸 기억해두길 바란다.
2. 시퀀스 (sequences)
시퀀스는 가변(mutable) 시퀀스와 불변(immutable) 시퀀스가 존재한다. 불변 시퀀스는 말 그대로 값을 삭제, 수정할 수 없다. 아래에서 설명하겠다.
세 가지 기본 시퀀스 형이 존재한다.
- 가변 시퀀스
- 리스트 (list)
- 불변 시퀀스
- 튜플 (tuple)
- 범위 (range)
a = [1, 2]
a.append(0)
a.pop(0)
b = []
c = [3, 4, [5, 6, [7, 8]]]
d = c[1:]
print(a) # [2, 0]
print(type(b)) # <class 'list'>
print(c[2][2][1]) # 8
print(d) # [4, [5, 6, [7, 8]]]
먼저 리스트는 가변 시퀀스다. 이건 뭐 쉬우니 설명할 게 없다. 중괄호([, ])를 사용하는 것을 기억하면 된다. 인덱스는 0부터 시작한다. [i:j] 형태로 슬라이싱 할 수 있다.
리스트는 배열로 구현돼있을까? 아니면 링크드 리스트로 구현돼있을까? 구현체에 따라 다르겠지만 CPython에서는 variable length array로 구현돼있다고 한다. 확인은 안해봤지만 다른 구현체도 아마 var-length array로 되어 있을 것이다.
링크드리스트를 사용하고 싶으면 collections.deque
등을 사용해야 한다.
a = (1, 2.3, (4, 5+6j))
print(type(a)) # <class 'tuple'>
print(a[0]) # 1
a[0] = 3 # TypeError: 'tuple' object doesn't support item assignment
del(a[0]) # TypeError: 'tuple' object doesn't support item deletion
튜플은 불변 시퀀스로 괄호((, ))를 사용해 생성할 수 있다. 불변 시퀀스이기 때문에 수정이나 삭제를 할 수 없다. 수정하려고 하면 TypeError
를 raise한다.
슬라이싱, 인덱싱 등 나머지 속성은 리스트와 똑같다.
# class range(stop)
# class range(start, stop[, step])
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(0, 30, 5))
[0, 5, 10, 15, 20, 25]
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(0, -10, -1))
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> list(range(0))
[]
>>> list(range(1, 0))
[]
range 형은 숫자의 불변 시퀀스를 나타낸다. 이때 인자는 모두 정수형이 필요하다. start의 기본값은 0, step의 기본값은 1이다.
추가적으로 텍스트, 바이너리 시퀀스가 있다.
- 텍스트 시퀀스 (string)
- 바이너리 시퀀스
- bytes
- bytearray
- memoryview
# builtins.py
class str(object):
"""
str(object='') -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to sys.getdefaultencoding().
errors defaults to 'strict'.
"""
파이썬의 문자열 클래스는 str
인데 불변 시퀀스임에 주의하자. 작은 따옴표, 큰 따옴표 아무거나 써서 만들 수 있고, 작은 따옴표나 큰 따옴표를 양쪽에 세 개씩 쓰면 여러 줄에 걸쳐 만들 수 있다.
str은 꽤 복잡하게 구현돼있다. 이 블로그에 자세하게 설명돼있다
바이너리 시퀀스는 bytes, bytearray가 있고 memoryview에 의해 지원된다고 한다.
3. 매핑 (mappings)
매핑은 사전(dict=dictionary)으로 표현되기도 한다. Key-Value를 저장하는 형식이다. 가변 객체이다.
>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> type(a)
<class 'dict'>
>>> a == b
True
>>> a.get('one') == b['one']
True
dict
생성자를 사용해도 되고, object 형식을 사용해도 된다. 단 object 형식으로 쓸 때는 key를 문자열 형식으로 입력해야 한다. dict 키워드를 사용할 때는 kwargs로 입력했을 때 name=value pair로 만들어준다.
get 메소드나 [] 연산자로 접근할 수 있다
4. 예외 (exceptions)
try:
with open('config.json', 'r', encoding='UTF8') as f:
config = json.load(f)
except IOError:
config = {}
finally:
print("config 생성 완료")
파이썬에서 예외는 BaseException
에서 파생된 클래스의 인스턴스들이며, try - except 구문으로 예외를 던지고 받을 수 있다. C의 try catch 생각하면 된다.
try_stmt ::= try1_stmt | try2_stmt
try1_stmt ::= "try" ":" suite
("except" [expression ["as" identifier]] ":" suite)+
["else" ":" suite]
["finally" ":" suite]
try2_stmt ::= "try" ":" suite
"finally" ":" suite
이걸 뭐라고 하더라? 분명 컴파일러 시간에 배운건데... 암튼 위 토큰 형식을 보면 어떻게 쓰는 지 대충 감이 올 것이다. try로 구문 감싸고, except에서 처리하고 else는 예외가 없었을 때 실행된다. finally는 예외 유무에 상관없이 실행된다.
예외는 raise
로 명시적으로 생성할 수도 있다.
'프로그래밍 > Python' 카테고리의 다른 글
[Python] 문자열 뒤집기 (0) | 2020.10.31 |
---|---|
Python3 typing.Optional (0) | 2020.08.07 |
Python3 requests 네이버 로그인 구현 (6) | 2020.03.16 |
Python3 json dump 한글 깨짐 해결방법 (0) | 2020.03.14 |
Python3 pip로 lxml 라이브러리 설치가 안될 때 (0) | 2020.03.14 |