* 목차
1. 주석
2. 변수
3. 연산자
4. 변수 선언
5. 조건문
6. 반복문
7. 함수
8. 클래스
주석(Comments)
python에서 지원하는 주석인 #과, 주석처럼 사용하는 Triple quotes가 있습니다. Triple quotes는 실제로는 string 객체지만, 주석으로 사용을 많이 합니다.
Comment : #을 사용하며, 글자 뒤에 한 줄만 적용 됩니다. print해도 출력할 수 없습니다.
# 주석1 입니다.
# 주석2 입니다.
Triple quotes : 큰 따옴표, 작은 따옴표를 사용하여 여러 줄에 적용합니다. print로 출력할 수 있습니다.
"""
document explain1
document explain2
"""
'''
document explain1
document explain2
'''
변수(Variable)
python에서 지원하는 다양한 Type이 있습니다.
None Type : 아무것도 아님을 나타내는 Type입니다.
None # NoneType : NULL, null, 없음을 뜻하는 객체
Boolean Types : 참, 거짓을 나타내는 논리적 Type입니다.
True # True == 1이다.
False # False == 0이다. 참고로 None은 True, False와 모두 일치하지 않는다.
Numeric Types : 숫자를 표현하는 Type입니다. int, float, complex가 있습니다.
# int
10
int(4.2) # 4
int('42') # 42
# float
3.14
float(3) # 3.0
float('3.14') # 3.14
# complex
(3.25 + 20j) # 허수를 j로 표현합니다.
complex(3.14, 9.9) # 3.14+9.9i
Sequence Types : 시퀀스 Type입니다. 각 요소를 index를 통해 접근할 수 있습니다.
# list : 나열 개체
[1, 1, 2]
list([1, 2, 3])
# tuple : 수정이 허용되지 않는 나열 개체
(1, 2, 3)
tuple([1, 2, 3])
# range(start=0, stop, step=1) # range : 시작, 끝, 단계를 가지고 있는 나열
range(5) # [0, 1, 2, 3, 4]를 출력할 수 있다.
range(0, 5) # [0, 1, 2, 3, 4]를 출력할 수 있다.
range(0, 5, 1) # [0, 1, 2, 3, 4]를 출력할 수 있다.
Text Sequence Types : 문자열(String) Type입니다. Single quote와 Double quotes, Triple quotes 형식이 있습니다.
# Single quotes. 안에 큰 따옴표가 필요할 때 사용한다.
'ab"cd"efgh'
# Double quotes. 안에 작은 따옴표가 필요할 때 사용한다.
"ab'cd'efgh"
# triple quotes. new line도 표현하고자 할 때 사용한다.
"""
ab'cd'
efgh
"""
'''
ab"cd"
efgh
'''
Binary Sequence Types : 이진 시퀀스 Type입니다. Bytes, Bytearray, Memoryview가 있습니다.
>>> a = b'abc' # bytes 선언. 변경할 수 없는 ascii 데이터이다.
>>> bytes(3) # int값을 넣으면 비어있는 byte를 3칸 생성한다.
b'\x00\x00\x00'
>>> bytes([1, 2, 3]) # list 형태로 선언할 시, 0 ~ 255 int값만 허용한다.
b'\x01\x02\x03'
>>> bytes(list(range(256))) # 한번 해보시길 추천.
>>> a = bytes(
b"""
abcd
efgh
""") # bytes도 string과 마찬가지로 '', "", """문법을 지원한다.
>>> "hello".encode() # string에서 encoding하면 bytes로 전환한다.
b'hello'
>>> b'\x61\x62\x63'.decode() # bytes를 decoding하면 string으로 전환한다.
'abc'
>>> repr(b'\x61\x62\x63') # 바이트 표현을 문자열 표현으로 전환한다.
b'abc'
>>> a = bytearray(b'hello') # bytsarray선언. 변경 가능한 byte data이다.
>>> a[0] += 1 # bytes type에서는 불가능한 동작이다.
>>> print(a)
bytearray(b'iello')
>>> byte_data = bytearray(b'hello') # memoryview는 byte-like(+array) data만 viewing할 수 있다.
>>> mem_v = memoryview(byte_data) # memoryview는 python에서 pointer같이 동작한다.
>>> mem_v
<memory at 0x000001C1067C8A00> # memoryview는 주소 그 자체이다.
>>> mem_v
>>> mem_v.obj # memoryview가 가리키고 있는 값
bytearray(b'hello')
>>> hex(id(mem_v.obj)) # memoryview가 가리키는 주소
'0x1c1068221b0'
>>> hex(id(byte_data)) # 그 주소가 byte_data 주소와 동일한지 확인
Set Types : 순서가 없고 중복이 불가능한 Type입니다. 순서가 있는 sequence보다 성능면에서 유리합니다.
# set : 수정이 가능한 set 객체
{1, 2, 3}
set([1, 2, 3])
# frozen set : 수정이 불가능한 set 객체
frozenset([1, 2, 3])
순서가 없기 때문에, index 사용이 불가합니다.
>>> a = {1, 2, 3}
>>> a[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object is not subscriptable
Dict Types : 순서가 없고 중복이 불가능한 key-value 기반의 Type입니다.
{'a': 1, 'b': 2}
dict([('a', 1), ('b', 2)])
연산자(Operator)
연산자는 여러가지 기호들로 되어 있으며, 각 기호는 함수와 대응됩니다.
주석에는 예상 결과값과 연산자에 대응되는 함수를 표기했습니다.
산술(Arithmetic) 연산자.
+11 # 11 pos(a)
-11 # -11 neg(a)
11 + 2 # 13 add(a, b)
11 - 2 # 9 sub(a, b)
11 * 2 # 22 mul(a, b)
11 / 2 # 5.5 truediv(a, b)
11 // 2 # 5 floordiv(a, b)
11 % 2 # 1 mod(a, b)
11 ** 2 # 121 pow(a, b)
비교(Comparison) 연산자
1 == 1 # True eq(a, b)
1 != 2 # True ne(a, b)
1 < 2 # True lt(a, b) less than
2 > 1 # True gt(a, b) greater than
0 <= 0 # True le(a, b) less and even
1 >= 1 # True ge(a, b) greater and even
비트(Bitwise) 연산자
5 & 9 # AND : 0b101 & 0b1001 = 0b0001 (1) and_(a, b)
5 | 9 # OR : 0b101 | 0b1001 = 0b1101(13) or_(a, b)
5 ^ 9 # XOR : 0b101 ^ 0b1001 = 0b1100(12) xor(a, b)
9 << 1 # left shift : 0b1001 << = 0b10010(18) lshift(a, b)
9 >> 1 # right shift : 0b1001 >> = 0b 100 (4) rshift(a, b)
~9 # inversion 0b....1001 = 0b11..10110(-10) invert(a)
할당(Assignment) 연산자. 산술연산자, 비트연산자 뒤에 =을 붙이면 연산한 뒤, 변수에 그대로 할당된다.
a = 11
a =+ 2 # 13
논리(Logical) 연산자
a = 1000
b = 1000
a is b # False is_(a, b)
a is not b # True is_not(a, b)
c = 1000
d = c # 얕은 복사 (shallow copy)
c is d # True is_(a, b)
e = True
not e # False not_(a)
시퀀스(Sequence) 관련 연산자
a = [1, 2]
b = [3, 4]
1 in a # True contains(seq, obj)
a + b # [1, 2, 3, 4] concat(seq1, seq2) seq끼리는 덧셈이 concat으로 동작.
a * 2 # [1, 2, 1, 2] concat(seq1, seq2)*2 concat 반복동작.
* seq에서 + 연산자는 broadcasting 동작이 아닌 concat으로 동작한다. 이렇게 연산되는 객체가 다른 Type을 가질 경우, 동작을 다르게 하는 경우가 있다. 다른 연산자는 동작하지 않는다.
>>> a = [1, 2]
>>> b = [3, 4]
>>> b - a # seq에 대해서 a - b 동작은 정의가 안되어 있다.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for -: 'list' and 'list'
* numpy array를 위한 행렬 곱 연산자로 "@"를 사용할 수 있지만 이 얘기는 numpy에서 다루도록 하겠습니다.
변수 선언(Declaring a variable)
python은 변수를 선언할 때 형식을 미리 지정하지 않고, 값에 따라 변수의 데이터 타입을 자동으로 정합니다. 이를 동적 타입핑(Dynamic Typing)이라 합니다.
>>> a = 1
>>> type(a) # type은 변수의 형식을 알아내는 함수이다.
<class 'int'>
>>> a = 1.1 # int(정수) 변수에 float(소수) 변수값을 대입했다.
>>> type(a)
<class 'float'> # float로 출력되는 것을 볼 수 있다.
C언어나 Java를 하신 분이라면 위와 같은 예시는 꿈도 못꿀 예시입니다. 이전 프로그래밍에서는 변수는 Type이 미리 지정이 되어야 하고, Type이 변경되면, 꼭 어떤 Type으로 변경할 지 명시 해야 합니다.
/**
* C++ code에서 변수 선언 예시
*/
int a = 1; // int 형식의 a 변수 선언
vector<float> b = {}; // vector<float> 형식의 b 선언.
b.push_back((float)a); // a를 float로 type 변경 후 b에 삽입.
cout << b[0] << endl; // 1 출력
하지만 Python은 Type을 변수의 값에 맞춰 스스로 변경합니다. 이런 방법은 개발자의 편의성을 증대시키지만, 개발자 스스로에게 책임감있는 행동을 강요합니다. 데이터 type을 제대로 관리하지 않으면 다음과 같은 사고가 발생할 수 있습니다.
>>> a = [1, 2, 3] # a를 list로 선언
>>> a == True # 누군가가 a가 bool type으로 생각해 True와 비교함.
False # a는 False구나....라는 오해가 생김.
위의 예시는 매우 짧은 코드이므로, 실제로 저런 상황은 발생하지 않을 것입니다. 하지만 만약, 10000줄이 넘어가는 코드라면 어떨까요? 이러한 문제를 방지하기 위해 Python은 Type hints를 지원합니다.
a: int = 10 ## int type의 변수라는 hint
하지만 hint는 hint일 뿐, 강제되는 사항은아니고, hint를 어긴다고 프로그램이 종료되지는 않습니다. 그래도 개발하는 과정을 좀 더 명확히 해주기 때문에, 중요한 부분은 작성하면 좋을 듯 합니다.
조건문(Conditional statements)
python의 조건문은 가독성이 매우 뛰어납니다.
checked = True
if checked == True:
print("it is checked")
elif checked == False:
print("it is not checked")
else:
print("Not predicted value")
python의 if문이 특이한 점은 다음과 같습니다.
1. if 키워드 후에 괄호( )를 사용하지 않음
2. ":"로 if 문을 마무리
3. if문 조건성립 시 실행할 구문을 중괄호{ }가 아닌 4칸 띄어서 표현
4. if문이 끝나고 다음 조건을 elif, else 키워드 활용
덕분에 괄호 지옥에서 벗어나 깔끔한 코드 작성을 할 수 있게 되었습니다.
심지어 flag를 bool type으로 비교하므로 ==을 is로 바꿔서 사용해도 됩니다.
checked = True
if checked:
print("it is checked")
elif checked is False:
print("it is not checked")
else:
print("Not predicted value")
가독성을 추구하는 python 답게, if문 작성이 매우 쉽고 보기 편합니다. 참고로 C++의 if문은 다음과 같습니다.
bool checked = true;
if(checked) {
cout << "a is checked" << endl;
} else if(checked == false) {
cout << "a is not checked" << endl;
} else {
cout << "not predict value" << endl;
}
반복문(looping statements)
python에는 반복문에는 for문과 while문 2가지가 있습니다. 이 2가지 반복문 또한 블럭 단위를 { }로 표현하지 않고 있습니다.
1. 몇 번 반복할 지, 혹은 어떤 나열을 확인할 지 정확히 알고 있음 : for문 사용하기
a = [1, 2, 3, 4, 5, 6]
for i in range(len(a)): ## a 길이만큼 반복
a[i] *= 2
print(a) # 2, 4, 6, 8, 10, 12
python에서는 for(i = 0; i < size ; i++) 와 같은 for문이 없습니다. 대신 for i in range(number)로 대체되었습니다.
range는 Sequence 타입입니다. 만약 range 대신 다른 Sequence Type을 사용해도 for문은 돌아갑니다.
a = [1, 2, 3, 4, 5, 6]
b = []
for a_element in a: ## a의 원소를 a_element라 칭하며, a의 원소 개수만큼 반복
b.append(a_element * 2)
print(b) # 2, 4, 6, 8, 10, 12
2. 반복횟수가 명확하진 않지만, 어떤 조건에 반복이 끝날 지 알고 있음 : while문 사용하기.
a = [1, 2, 3, 4, 5, 6]
b = []
index = 0
## index가 a길이보다 작으면서, a[index]가 5보다 작을 때까지 반복
while len(a) > index and a[index] < 5:
b.append(a[index]*2)
index += 1 ## index를 증가하여, 무한반복에 빠지지 않게 한다.
print(b) # 2, 4, 6, 8
조건이 잘못 설정되는 경우 무한 loop를 돌 수 있습니다. while문이 반드시 필요한 것이 아니라면, for문을 되도록 사용하도록 합시다.
함수(Function)
함수는 def 키워드와 return를 사용합니다. 함수를 여기에서 설명하기에는 너무 내용이 길어져 간단한 형식만 남깁니다.
def add2(number):
return number + 2
def no_return_function(number):
number = 0
def add_numbers(num1, num2):
return num1+num2;
print(add2(3)) # 5
print(no_return_function(5)) # None
print(add_numbers(10, 12)) # 22
클래스(Class)
class는 class 키워드, self로 변수참조와, __init__등 magic method가 존재합니다. 클래스를 여기에서 설명하기에는 너무 내용이 길어져 간단한 형식만 남깁니다.
class Car:
price = 10
def __init__(self, model):
self.model = model
def model_change(self, change_model):
self.model = change_model
def get_model(self):
return self.model
def get_price(self):
return self.price
* reference
https://docs.python.org/3/library/typing.html
'Python > Basic' 카테고리의 다른 글
Python - List Comprehension (0) | 2023.03.19 |
---|---|
Python - Int의 크기가 28bytes인 이유 (5) | 2023.03.01 |
Python - Mutable vs Immutable (2) | 2023.02.26 |
Python - List는 어떻게 데이터를 관리하는가? (0) | 2023.02.15 |
Python - is와 ==의 차이 (1) | 2023.02.10 |