Study/CODE 3기 [Jump to python]

[김이김이나] python 스터디 4주차

xosdrweds 2024. 3. 31. 17:26

  • 작성자: 김민혁
  • 작성일: 3/31
  • 진도: [5-1] 클래스

📌클래스란 무엇인가?

클래스란 똑같은 무언가를 계속 만들어 낼 수 있는 설계 도면을 말한다
클래스로 만든 객체에는 중요한 특징이 있다. 바로 객체마다 고유한 성격을 가진다는 것이다.
동일한 클래스로 만든 객체들은 서로 전혀 영향을 주지 않는다.
 

<사칙 연산 클래스 만들기>

이러한 클래스를 만들어보자
 

<클래스 구조 만들기>

 
일단은 아무런 기능이 없어도 되기 때문에 매우 간단하게 만들 수 있다. 다음을 따라 해 보자.

>>> class FourCal:
...     pass

먼저 대화형 인터프리터에서 pass라는 문장만을 포함한 FourCal 클래스를 만든다. 현재 상태에서 FourCal 클래스는 아무 변수나 함수도 포함하지 않지만, 우리가 원하는 객체 a를 만들 수 있는 기능은 가지고 있다. 

pass는 아무것도 수행하지 않는 문법으로, 임시로 코드를 작성할 때 주로 사용한다.

 

<객체에 연산할 숫자 지정하기>

>>> a = FourCal()

생성된 객체 a는 아직 아무런 기능도 하지 못한다.
이제 더하기, 빼기, 곱하기, 나누기 등의 기능을 하는 객체를 만들어야 한다.
그런데 이러한 기능을 갖춘 객체를 만들려면 먼저 사칙 연산을 할 때 사용할 2개의 숫자를 a 객체에게 알려 주어야 한다.
다음과 같이 연산을 수행할 대상(4, 2)을 객체에 지정할 수 있게 만들어 보자.

>>> a.setdata(4, 2)

위 문장이 동작하려면 다음과 같이 FourCal 클래스를 다시 정의해야 한다.

>>> class FourCal:
...     def setdata(self, first, second):
...         self.first = first
...         self.second = second

앞에서 만든 FourCal 클래스에서 pass 문장을 삭제하고 그 대신 setdata 함수를 정의했다.
클래스 안에 구현된 함수는 다른 말로 메서드(method)라고 부른다.
일반적인 함수를 만들 때는 다음과 같이 소스 코드를 작성한다.

def 함수_이름(매개변수):
    수행할_문장
    ...

메서드도 클래스에 포함되어 있다는 점만 제외하면 일반 함수와 다를 것이 없다.
setdata 메서드를 다시 보면 다음과 같다.

def setdata(self, first, second):   # 메서드의 매개변수
    self.first = first              # 메서드의 수행문
    self.second = second            # 메서드의 수행문

 

<setdata 메서드의 매개변수>

setdata 메서드는 매개변수로 self, first, second 3개의 입력값을 받는다.
그런데 일반 함수와 달리, 메서드의 첫 번째 매개변수 self는 특별한 의미를 가진다.
파이썬 메서드의 첫 번째 매개변수 이름은 관례적으로 self를 사용한다.
 

<setdata 메서드의 수행문>

def setdata(self, first, second):   # 메서드의 매개변수
    self.first = first              # 메서드의 수행문
    self.second = second            # 메서드의 수행문

a.setdata(4, 2)처럼 호출하면 setdata 메서드의 매개변수 first, second에는 각각 값 4와 2가 전달되어
setdata 메서드의 수행문이 다음과 같이 해석된다.

self.first = 4
self.second = 2

self는 전달된 객체 a이므로 다시 다음과 같이 해석된다.

a.first = 4
a.second = 2

a.first = 4라는 문장이 수행되면 a 객체에 객체변수 first가 생성되고 4라는 값이 저장된다.
이와 마찬가지로 a.second = 2라는 문장이 수행되면 a 객체에 객체변수 second가 생성되고 2라는 값이 저장된다.
이번에는 다음과 같이 a, b 객체를 만들어 보자.

>>> a = FourCal()
>>> b = FourCal()

그리고 a 객체의 객체변수 first를 다음과 같이 생성한다.

>>> a.setdata(4, 2)
>>> a.first
4

이번에는 b 객체의 객체변수 first를 다음과 같이 생성한다.

>>> b.setdata(3, 7)
>>> b.first
3

 
a 객체의 first 값은 b 객체의 first 값에 영향받지 않고 원래 값을 유지하고 있다는 것을 확인할 수 있다.
클래스로 만든 객체의 객체변수는 다른 객체의 객체변수에 상관없이 독립적인 값을 유지한다.

 

<더하기 기능 만들기>

>>> class FourCal:
...     def setdata(self, first, second):
...         self.first = first
...         self.second = second
...     def add(self):
...         result = self.first + self.second
...         return result

add 메서드를 새롭게 추가했다. 이제 클래스를 사용해 보자.

>>> a = FourCal()
>>> a.setdata(4, 2)

위와 같이 호출하면 앞에서 살펴보았듯이
a 객체의 first, second 객체변수에는 각각 값 4와 2가 저장될 것이다.
이제 add 메서드를 호출해 보자.

>>> a.add()
>>> 6

a.add()라고 호출하면 add 메서드가 호출되어 값 6이 출력될 것이다.
어떤 과정을 거쳐 값 6이 출력되는지 add 메서드를 따로 떼어 내 자세히 살펴보자.

def add(self):
    result = self.first + self.second
    return result

add 메서드의 매개변수는 self, 리턴값은 result이다.
리턴값인 result를 계산하는 부분은 다음과 같다.

result = self.first + self.second

a.add()와 같이 a 객체에 의해 add 메서드가 수행되면
add 메서드의 self에는 객체 a가 자동으로 입력되므로 이 내용은 다음과 같이 해석된다.

result = a.first + a.second

a.first와 a.second는 add 메서드가 호출되기 전에 
a.setdata(4, 2) 문장에서 a.first = 4, a.second = 2로 설정된다. 따라서 위 문장은 다시 다음과 같이 해석된다.

result = 4 + 2

따라서 다음과 같이 a.add()를 호출하면 6을 리턴한다.

>>> a.add()
6

 

 

<곱하기, 빼기, 나누기 기능 만들기>

>>> class FourCal:
...     def setdata(self, first, second):
...         self.first = first
...         self.second = second
...     def add(self):
...         result = self.first + self.second
...         return result
...     def mul(self):
...         result = self.first * self.second
...         return result
...     def sub(self):
...         result = self.first - self.second
...         return result
...     def div(self):
...         result = self.first / self.second
...         return result

mul, sub, div 모두 add 메서드의 방법과 같다.
 

📌클래스의 상속

어떤 클래스를 만들 때 다른 클래스의 기능을 물려받을 수 있게 만드는 것이다.
이번에는 상속 개념을 사용하여 우리가 만든 FourCal 클래스에 a의 b제곱 값을 구할 수 있는 기능을 추가해 보자.
앞에서 FourCal 클래스는 이미 만들어 놓았으므로
FourCal 클래스를 상속하는 MoreFourCal 클래스는 다음과 같이 간단하게 만들 수 있다.

>>> class MoreFourCal(FourCal):
...     pass

클래스를 상속하기 위해서는 다음처럼 클래스 이름 뒤 괄호 안에 상속할 클래스 이름을 넣어주면 된다.

class 클래스_이름(상속할_클래스_이름)

MoreFourCal 클래스는 FourCal 클래스를 상속했으므로 FourCal 클래스의 모든 기능을 사용할 수 있다.
이제 원래 목적인 a의 b제곱을 계산하는 MoreFourCal 클래스를 만들어 보자.

>>> class MoreFourCal(FourCal):
...     def pow(self):
...         result = self.first ** self.second
...         return result

pass 문장은 삭제하고 위와 같이 두 수의 거듭제곱을 구할 수 있는 pow 메서드를 추가했다.
그리고 다음과 같이 pow 메서드를 수행해 보자.

>>> a = MoreFourCal(4, 2)
>>> a.pow()
16
>>> a.add()
6

MoreFourCal 클래스로 만든 a 객체에 값 4와 2를 지정한 후
pow 메서드를 호출하면 4의 2제곱(42)인 16을 리턴하는 것을 확인할 수 있다.
상속받은 기능인 add 메서드도 잘 동작한다.
상속은 MoreFourCal 클래스처럼 기존 클래스(FourCal)는 그대로 놔둔 채 클래스의 기능을 확장할 때 주로 사용한다.
 

📌매서드 오버라이딩

>>> a = FourCal(4, 0)
>>> a.div()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    result = self.first / self.second
ZeroDivisionError: division by zero

FourCal 클래스의 객체 a에 값 4와 0을 지정하고 div 메서드를 호출하면
4를 0으로 나누려고 하므로 ZeroDivisionError 오류가 발생한다.
0으로 나눌 때 오류가 아닌 값 0을 리턴받고 싶다면 어떻게 해야 할까?
다음과 같이 FourCal 클래스를 상속하는 SafeFourCal 클래스를 만들어 보자.

>>> class SafeFourCal(FourCal):
...     def div(self):
...         if self.second == 0:  # 나누는 값이 0인 경우 0을 리턴하도록 수정
...             return 0
...         else:
...             return self.first / self.second

FourCal 클래스에 있는 div 메서드를 동일한 이름으로 다시 작성했다.
이렇게 부모 클래스(상속한 클래스)에 있는 메서드를 동일한 이름으로
다시 만드는 것을 메서드 오버라이딩(method overriding)이라고 한다.
이렇게 메서드를 오버라이딩하면 부모 클래스의 메서드 대신 오버라이딩한 메서드가 호출된다.
SafeFourCal 클래스에 오버라이딩한 div 메서드는 나누는 값이 0인 경우에는 0을 리턴하도록 수정했다.
이제 다시 앞에서 수행한 예제를 FourCal 클래스 대신 SafeFourCal 클래스를 사용하여 수행해 보자.

>>> a = SafeFourCal(4, 0)
>>> a.div()
0

FourCal 클래스와 달리 ZeroDivisionError가 발생하지 않고 의도한 대로 0이 리턴되는 것을 확인할 수 있다.

📌클래스변수

이번에는 객체변수와는 성격이 다른 클래스변수에 대해 알아보자.

>>> class Family:
...     lastname = "김"

Family 클래스에 선언한 lastname이 바로 클래스변수이다.
클래스변수는 클래스 안에 함수를 선언하는 것과 마찬가지로 클래스 안에 변수를 선언하여 생성한다.
이제 Family 클래스를 다음과 같이 사용해 보자.

>>> Family.lastname
김

클래스변수는 위 예와 같이 클래스_이름.클래스변수로 사용할 수 있다.
또는 다음과 같이 Family 클래스로 만든 객체를 이용해도 클래스변수를 사용할 수 있다.

>>> a = Family()
>>> b = Family()
>>> a.lastname
김
>>> b.lastname
김

만약 Family 클래스의 lastname을 "박"이라는 문자열로 바꾸면 어떻게 될까? 다음과 같이 확인해 보자.

>>> Family.lastname = "박"
>>> a.lastname
박
>>> b.lastname
박

클래스변수의 값을 변경했더니 클래스로 만든 객체의 lastname 값도 모두 변경된다는 것을 확인할 수 있다.
즉, 클래스변수는 객체변수와 달리 클래스로 만든 모든 객체에 공유된다는 특징이 있다.


  • 작성자: 이나은
  • 작성일: 4/1
  • 진도: [5-2] 모듈 ~ [5-3] 패키지

📌모듈이란?

모듈이란 함수, 변수, 클래스를 모아 놓은 파이썬 파일이다.
모듈은 다른 파이썬 프로그램에서 불러와 사용할 수 있도록 만든 파이썬 파일이라고도 할 수 있다.
 
먼저 예제로 간단한 모듈을 만들어 보았다.

이 모듈에는 add와 sub 함수가 있고 파일명은 mod1.py이다.
이것이 바로 모듈이며, 모듈이라고 부르기는 하지만 일반 파이썬 파일과 같다.
 
명령형 프롬프트에서  mod1.py 모듈을 불러와 실행해보면 다음과 같이 함수가 실행됨을 알 수 있다.

함수를 사용하기 위해서는

모듈_이름.함수_이름

위와 같은 방식을 사용하며,
모듈을 불러오는 import의 경우

import 모듈_이름

위와 같은 방식을 사용한다. 함수 이름과 모듈 이름을 단독으로 쓰고 싶은 경우는

from 모듈_이름 import 모듈_함수

다음과 같이 사용하면 된다.

3번 방식을 사용하면 아까 만들어둔 mod1 모듈도 잘 작동하는 것을 확인할 수 있다.
여기서 모듈에 있는 여러가지 함수를 사용하고 싶을 경우

from 모듈_이름 import 함수1, 함수2 …

위와 같은 방식을 활용하면 되고, 모듈 안의 함수를 전부 사용하고 싶으면

from 모듈_이름 import *

이 방식을 사용할 수 있다. 여기서 * 문자는 모든 것이라는 뜻이며
*를 붙인 것은 모든 함수를 사용하는 것이라고 해석할 수 있다.
 

📌 if__name__==”__main__”:

 
이번에는 위와 같이 mod1모듈을 print를 붙여 수정해보았다.
하지만 이 mod1.py을 명령 프롬프트 창에서 실행해보면, import를 수행하는 순간
print 결괏값을 출력한다. 하지만 우리가 사용하고 싶은 것은 함수이므로 이러한 문제를
방지하려면 다음과 같이 파일을 수정하면 된다.

여기서 if __name__ == "__main__": 은 참과 거짓을 생각하여 if문을 수행하는데,
이는 파일을 직접 실행했을 때는 참이 되어 if문 다음을 수행하고
대화형 인터프리터나 다른 파일에서 이 모듈을 불러 실행할 때는 거짓이 되어 if문을 수행하지 않는다.

언급했던 것처럼 대화형 인터프리터를 사용하면
다음과 같이 아무것도 실행되지 않는 것을 확인할 수 있다.
 
**여기서 name 변수란?
파이썬이 내부적으로 사용하는 특별한 변수 이름이다. 만약 파일을 직접 실행하면 __name__ 변수에는 __main__ 값이 저장된다.
하지만 다른 파이썬 모듈에서 실행하면 변수에 mod1.py의 모듈 이름인 mod1이 저장된다.
 

📌클래스나 변수를 포함한 모듈

모듈은 클래스나 변수를 포함할 수도 있는데, 다음과 같은 예제를 통해 알아보자.

이 파일은 원의 넓이를 계산하는 Math 클래스와 add 함수, 변수를 모두 포함하고 있다.
이를 대화형 인터프리터에서 열어 실행해보면

 
첫번째로 PI 변수의 값을 사용한 것,
두번째로 Math 클래스를 사용한 것,
마지막으로 add 함수를 사용한 것까지 확인 가능하다.
 

📌다른 파일이나 디렉터리의 모듈 불러오기

위 주제에 대해 알아보기 위해 modest.py를 다음과 같이 생성해보자.

이처럼 다른 파이썬 파일에서도 import mod2를 통해 mod2 모듈을 불러와서 사용할 수 있다.
 
이번에는 다른 디렉터리에서 모듈을 불러오는 방법을 알아보기 위해 mod2.py 파일을 다른 디렉터(mymod)로 옮겼다.

그리고 sys.path에서 append를 사용해 디렉터리를 sys.path에 mymod 디렉터리를 추가했으므로 이제 디렉터리 이동 없이 모듈을 불러와서 사용할 수 있다.
 

📌패키지란?

패키지는 서로 관련 있는 모듈의 집합을 의미한다. 패키지는 파이썬 모듈을 디렉터리 구조로 관리할 수 있게 해준다.
이것을 알아보기 위해 점프 투 파이썬 책의 예제를 그대로 활용하였다.
책과 같이 game 디렉터리와 하위 디렉터리들을 생성하고 .py 파일도 생성해주었다.
이제 패키지를 사용하여 다양한 방법으로 echo_test 함수를 실행해보자.

첫번째는 import를 사용하여 실행하는 방법이 있고,

두번째는 from . . . import를 실행하는 방법,

세번째는 echo 모듈의 echo_test 함수를 직접 import하는 것이다.
 

📌__init__.py

아까 넘어갔던 __init__.py에 대해 알아보자.
__init__.py는 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.
지금 예제를 수행하면서 game, sound, graphic 디렉터리에 전부 이 파일을 넣어주었는데,
이는 이 디렉터리들을 패키지의 일부로 인식시켜준 것이다.
 

📌패키지 내에서의 변수, 함수 정의

또한 패키지 범위에서 변수와 함수를 적용할 수 있는데,

이는 game 디렉터리의 __init__.py를 수정하여 VERSION 이라는 변수와 함수를 적용한 것이다.
이는 다음과 같이 활용이 가능하다.

 

📌패키지 내의 모듈을 미리 import

위와 같이 패키지 내의 다른 모듈을 __init__.py 내에 미리 import 해놓으면 패키지를 사용하는 코드에서 쉽게 접근이 가능하다.
 

📌패키지  초기화

__init__.py에 패키지를 처음 불러올 때 실행되어야 하는 코드를 작성할 수 있다.

위 사진의 코드에서는 처음 패키지를 import할 때 초기화 코드가 실행되도록 해준 것이다.
단, 초기화 코드는 한번 실행된 후에는 다시 import를 수행해도 실행되지 않는다.
 

📌__all__

특정 디렉터리의 모듈을 *를 사용하여 import할 때는 디렉터리의 __init__.py에 __all__변수를 설정하고
import 할 수 있는 모듈을 정의해주면 된다.
__all__ 변수를 사용하지 않으면 *를 사용해도 오류가 뜨니 주의하자.
 

📌relative 패키지

예제의 graphic 디렉터리의 reneder.py 모듈에서 sound 디렉터리의 echo.py 모듈을 사용하고 싶을 때처럼
다른 디렉터리의 모듈을 사용하고 싶을 때에는 다음과 같이 from . . . import를 사용해 render.py 모듈을 수정하면 된다.

위의 방식대로 from . . . import를 사용하는 것 이외에도

다음과 같이 ..sound.echo를 from 다음에 쓸 수도 있는데, 
여기서  ..은 render.py 파일의 부모 디렉터리를 의미한다.
render.py 파일의 부모 디렉터리는 game 이므로 위와 같이 두 코드에서 import가 똑같이 실행되는 것이다.
참고로 .은 현재 디렉터리를 의미한다.


  • 작성자: 정현석
  • 작성일: 4/1
  • 진도: [5-4] 오류처리 ~ [5-5] filter

📌  파이썬에서 발생하는 다양한 오류

 
파이썬을 사용하다보면 수많은 오류들을 만나게 된다.
이러한 오류를 처리하는 방법을 알기 전에 오류가 발생하는 상황을 살펴볼 필요가 있다.
 
존재하지 않는 파일을 사용하려고 하면 어떻게 될까?

>>>  f = open("4월1일은만우절", 'r')
  File "<stdin>", line 1
    f = open("4월1일은만우절", 'r')
IndentationError: unexpected indent

 
다음과 같은 IndentationError 오류가 발생한다. 
 
다음으로 256을 0으로나누는 경우를 살펴보자.

>>> 256/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

 
이 경우 ZeroDivisionError 오류가 발생한다. 
 
마지막으로 요솟값이 3개 밖에 없는 a에서 4번째 요솟값을 호출해보자.
 

>>> a = [1, 2, 3]
>>> a[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

 
이 경우에는 IndexError가 발생한다. 
 
파이썬은 이러한 오류가 발생하면 프로그램을 중단하고 오류가 발생했음을 알려준다.
 

📌  오류 처리 방법

 

<try-expert 문>

오류를 처리하기 위한 try-expert문의 구조는 다음과 같다.
 

try:
    ...
expert [발생오류 [as 오류변수]]:
    ...

 
try 블록 수행 중에 오류가 발생하게 되면 expert 블록이 수행된다.
반대로 try 블록에서 오류가 발생하지 않으면 expert 블록은 수행되지 않는다.
 
expert 구문을 조금 더 자세히 알아보자.
 

expert [발생오류 [as 오류변수]]:

 
해당 구문은 []를 사용하는데, 이 기호는 괄호 안의 내용을 생략할 수 있다는 표현이다.
expert 구문은 다음과 같은 3가지 방법으로 사용된다.
 

1. try-except 만을 쓰는 방법

 

try:
    ...
expert 
    ...

 
이 경우 오류의 종류와 관계없이 오류가 발생하면 except 블록을 수행한다.
 

2. 발생 오류만 포함한 except 문

 

try:
    ...
expert 발생오류 :
    ...

 
이 경우 오류가 발생했을 때 except문에 미리 정해 놓은 오류와 동일한 오류일 경우에만 except 블록을 수행한다.
 

3. 발생 오류와 오류 변수까지 포함한 except 문

 

try:
    ...
expert 발생오류 as 오류변수:
    ...

 
이 경우는 오류의 내용까지 알고 싶은 경우에 사용하는 오류 처리 방법이다.
발생 오류와 오류 변수까지 포함한 except 문의 예시를 살펴보자.

try:
    256/0
except ZeroDivisionError as e:
        print(e)

위처럼 256을 0으로 나누려고 하면 ZeroDivisionError 가 발생하여 except 블록이 실행된다.
이어서 오류 변수 e에 담기는 오류 메시지를 출력할 수 있다.
 

📌  여러가지 오류 처리 방법

 
하나의 문장 안에서 여러 개의 오류가 발생하게 되면 어떻게 오류를 처리해야할까?
다음과 같은 방법을 통해 여러 개의 오류를 처리할 수 있다.
다음 예제를 통해 2가지 오류를 처리하는 방법을 알아보자.

try:
    ...
except 발생오류1:
    ...
except 발생오류2:
    ...

따라서 앞서 살펴보았던 0으로 나누는 오류와 인덱싱 오류를 다음과 같이 처리할 수 있다.

try:
    a = [1, 2]
    print(a[4])
    256/0
except ZeroDivisionError:
    print("숫자 0으로는 나누기는 불가능합니다.")
except IndexError: 
    print("인덱싱은 불가능합니다.")

위 예시에서 a는 두 개의 요솟값을 갖고 있으므로 세 번째 요솟값을 출력하는 것은 불가능하다.
따라서 파이썬은 IndexError를 발생시켜 "인덱싱은 불가능합니다."라는 문자열을 출력한다.
인덱싱 오류가 가장 먼저 발생한 오류이므로 이후에 발생할 예정인 ZeroDivisionError 오류는 발생하지 않는다.

📌 abs

 
abs(x)는 어떤 숫자를 입력받으면 그 숫자의 절댓값을 리턴하는 함수이다.

>>> abs(47)
47
>>> abs(-1026)
1026
>>> abs(-3.14)
3.14

 

📌 all

 
all(x)는 반복 가능한 x를 입력값으로 하여 x 값이 빠짐없이 모두 참이면 True를, 그렇지 않다면 False를 출력한다.
여기서 반복 가능한 값은 for문을 사용할 수 있는 리스트, 튜플, 문자열, 딕셔너리, 집합 등의 자료형을 의미한다. 

>>> all ( [16, 32, 64] )
True

리스트  [16, 32, 64] 의 값은 모두 참이므로 True를 리턴한다.

>>> all ( [16, 32, 64, 0] )
False

리스트 중에서 요소 0은 거짓이므로 False를 리턴한다.
 

📌any

 
any(x)는 반복 가능한 데이터 x를 입력받아 x의 요소 중 하나라도 참이 있으면
True를 리턴하고가 모두 거짓일 때만 False를 리턴한다. 
다음의 예시를 살펴보자.

>>> any([1, 2, 3, 0])
True

리스트 [1, 2, 3, 0] 중에서 1,2,3이 참이므로 True를 리턴한다.

>>> any(["", 0])

 

📌chr

 
chr(i)는 유니코드 숫자 값을 입력받아 그 코드에 해당하는 문자를 리턴하는 함수이다.

>>> chr(97)
'a'
>>> chr(44032)
'가'

 

📌dir

dir은 객체가 지닌 변수나 함수를 보여주는 함수이다. 
다음 예시는 리스트와 딕셔너리가 지닌 함수를 보여준다.

>>> dir([1, 2, 3])
['append', 'count', 'extend', 'index', 'insert', 'pop' , ...]

 

📌enumerate

 
enumerate는 '열거하다'라는 뜻이다.
이 함수는 순서가 있는 데이터를 입력으로 받아 인덱스 값을 포함하는 객체를 리턴한다.

>>> for i, name in enumerate(['Khu', 'is', 'great']):
...         print(i, name)
...
0 Khu
1 is
2 great

위 예제에서 인덱스 값과 함께 Khu, is, great가 출력되었다.
enumerate 함수를 사용하면 이처럼 자료형의 현재 순서 인덱스와 그 값을 쉽게 알 수 있다.
 

📌eval

 
eval은 문자열로 구성된 표현식을 입력받아 해당 문자열을 실행한 결괏값을 리턴하는 함수이다.

>>> eval('1+2')
3
>>> eval(" 'big' + 'data' ")
'bigdata'

 

📌filter

 
filter란 '걸러내다' 라는 뜻으로, filter 함수 역시 이와 비슷한 역할을 한다.

filter(함수, 반복_가능한_데이터)

 filter 함수는 첫 번째 인수로 함수, 두 번째 인수로 그 함수에 차례대로 들어갈 반복 가능한 데이터를 받는다.
그리고 반복 가능한 데이터의 요소 순서대로 함수를 호출했을 때 리턴값이 참인 것만 묶어서 리턴한다.
filter 함수를 사용한 예시는 다음과 같다.

def positive(x):
      return x > 0

print(list(filter(positive, [2, -7, 6, -27, 3})))

다음과 같은 예제를 실행하면 [2, 6, 3]과 같은 실행 결과를 얻을 수 있다.
 


📌느낀점

이번 주차에는 배우고 체화해야할 내용이 방대해서 조금은 힘들었지만
그래도 막상 공부해보니 뿌듯하고 학습한 내용을 잊어버리지 않도록 복습하는 것이 중요하다고 생각하였다.



  • 작성자: 김서현
  • 작성일: 3/31
  • 진도: [5-5] hex ~ [5-5] zip

📌hex

hex (x)는 정수를 입력받아 16진수 문자열로 변환하여 리턴하는 함수이다.

16진수란? 
16을 밑으로 하는 기수법으로, 16진수에서 존재하는 숫자는 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f 16가지이다.
ex) 0f -> 16, 0ff -> 100
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, 10, 11, 12, 13 ... 29, 2a, 2b, 2c ... 

 

📌id

id는 객체를 입력받아 객체의 고유 주솟값을 리턴하는 함수이다.

여기서 3, a, b는 다 같다고 입력되었기 때문에 같은 값인 14073525274112를 출력한다.
 

📌input

input은 사용자 입력을 받는 함수이다.

 

📌int

int는 문자열 형태의 숫자나 소수점이 있는 숫자를 정수로 리턴하는 함수이다. 만약 정수가 입력되면 그대로 리턴한다.

만약, int(x, radix)일 때, x를 10진수로 바꾸어 리턴한다.

위 예시에서는 0x7b (16진수)를 10진수로 바꾸어 123을 출력하였다.
 

📌isintance

isintance 함수는 첫번째 인수로 객체, 두번째 인수로 클래스를 받는다.
입력으로 받은 객체가 그 클래스의 인스턴스인지를 판단하여 true, false를 리턴한다.

 

📌len

len은 입력값의 길이를 리턴하는 함수이다.

2번째 예시의 경우, 공백까지 포함하여 6자리임을 알 수 있다.
 

📌list

list는 반복 가능한 데이터를 입력받아 리스트로 만들어 리턴하는 함수이다.

 

📌map

map (f, iterable) 은 함수 (f)와 반복 가능한 데이터를 입력으로 받는다.
map은 입력받은 데이터의 각 요소에 함수 f를 적용한 결과를 리턴하는 함수이다.

위 예시에서는 1, 2, 3, 4, 5를 (f: )제곱한 값을 출력하였다.
 

📌max

max(iterable)은 인수로 반복 가능한 데이터를 입력받아 그 최댓값을 리턴하는 함수이다.

위 예시에서는 129301937894502984320이 가장 큰 수이기에 129301937894502984320을 출력하였다.
 

📌min

min(iterable)은 인수로 반복 가능한 데이터를 입력받아 그 최솟값을 리턴하는 함수이다.

위 리스트에서 가장 작은 수인 1을 출력하였다.
 

📌oct

oct(x)는 정수를 8진수 문자열로 바꾸어 리턴하는 함수이다.

8진수란?
0,1,2,3,4,5,6,7 8개의 숫자로만 표현하는 것이다.
0,1,2,3,4,5,6,7,10,11,12 ...

 

📌open

open(filename, [mode])은 파일 이름과 읽기 방법을 입력 받아 파일 객체를 리턴하는 함수이다.

w : 쓰기 모드로 파일 열기
r : 읽기 모드로 파일 열기
a : 추가 모드로 파일 열기
b : 바이너리 모드로 파일 열기

f = open ("seohyun_file", "rb")

 

📌ord

ord(c)는 문자의 유니코드 숫자 값을 리턴하는 함수이다. 문자의 순서 위치 값을 의미한다.
 

📌pow

pow(x,y)는 x를 y 제곱한 결괏값을 리턴하는 함수이다.

 

📌range

입력받은 숫자에 해당하는 범위 값을 반복 가능한 객체로 만들어 리턴한다.
 

<인수가 1개일 경우>

시작 숫자가 없기에 0부터 시작한다.  
 

<인수가 2개일 경우>

6부터 시작하여 11의 전 숫자까지 출력한다. 
 

<인수가 3개일 경우>

3번째 인수는 숫자 사이의 거리를 뜻한다.

 

📌round

round는 숫자를 입력받아 반올림해 리턴하는 함수이다.

두번째 예시는 숫자를 3자리까지만 반올림하여 표시할 수 있다.
 

📌sorted

sorted는 입력 데이터를 순서대로 정렬한 후 그 결과를 리스트로 리턴하는 함수이다.

 

📌str

str는 문자열 형태로 객체를 변환하여 리턴하는 함수이다.

 

📌sum

sum은 입력 데이터의 합을 리턴하는 함수이다.

리스트의 값들을 모두 더하여 값을 출력한다.
 

📌tuple

tuple은 반복 가능한 데이터를 튜플로 바꾸어 리턴하는 함수이다. 

입력에서 이미 튜플인 경우에는 그대로 출력하게 된다.
 

📌type

type는 입력값의 자료형이 무엇인지 알려주는 함수이다.
 

📌zip

zip은 동일한 개수로 이루어진 데이터들을 묶어서 리턴하는 함수이다. 

1-a, 2-b, 3-c, 4-d, 5-e 가 묶여 출력한다.


  • 작성자: 김한세
  • 작성일: 4/1
  • 진도: [5-6] ~ [5-6] os

📌표준 라이브러리

전 세계의 전문가들이 만든 프로그램들이 모여져 있는 곳이 바로 파이썬 표준 라이브러리이다.
이는 파이썬을 설치할 때 자동으로 컴퓨터에 설치된다.
어떤 라이브러리들이 존재하는지, 어떤 일을 할 때 어떤 라이브러리를 사용해야 하는지 익혀두어야 제대로 활용할 수 있다.
(04-4장에서 학습한 sys모듈과 08장 전체에서 다루게 될 re 모듈이 파이썬의 중요한 표준 라이브러리이나, 이번 챕터에서는 생략한다.)

<datetime.date>

연, 월, 일로 날짜를 표현할 때 사용하는 함수
아래와 같이 연, 월, 일을 인수로 하여 datetime.date 객체를 만들 수 있다.

두 개의 날짜 객체를 생성하였다. 이때 두 날짜의 차이를 쉽게 구할 수도 있다.

day2에서 day1을 뺐을 때 리턴되는 것은 datetime 모듈의 timedelta 객체이다.
이 객체를 diff 변수에 대입하고 이 diff 변수를 이용하여 두 날짜의 차이를 확인한 것이다.
요일도 간단하게 구할 수 있다. datetime.date 객체의 weekday 함수를 통해서이다.

0은 월요일을 의미하고 순서대로 1, 2, 3, 4, 5, 6은 각각 화, 수, 목, 금, 토, 일을 의미한다.
weekday 함수 대신 isoweekday 함수를 사용하면
1부터 7의 숫자가 차례대로 각각 월요일부터 일요일까지를 의미한다.

<time 모듈 함수 알아보기>

시간과 관련된 time 모듈에는 함수가 매우 많다. 그중 가장 유용한 몇 가지를 알아보자.

<time.time>

이 함수는 협정 세계 표준시를 기반으로 현재 시간을 리턴하는 함수이다.
1970년 1월 1일 0시 0분 0초를 기준으로 지난 시간을 초 단위로 리턴해 준다.

<time.localtime>

이 함수는 time.time()이 리턴한 실숫값을 사용해서 연, 월, 일, 시, 분, 초, ... 의 형태로 바꾸어 주는 함수이다.

<time.asctime>

이 함수는 localtime 함수가 리턴된 튜플 형태의 값을 인수로 받아서
날짜와 시간을 알아보기 쉬운 형태로 리턴하는 함수이다.

<time.ctime>

이 함수는 time.asctime(time.localtime(time.time())) 을 간단하게 표시한 것이다.
ctime이 asctime과 다른 점은 항상 현재 시간만을 리턴한다는 점이다.

<time.strftime>

이 함수는 시간에 관계된 것을 세밀하게 표현하는 여러 가지 포맷 코드를 제공한다.

time.strftime('출력할 형식 포맷 코드', time.localtime(time.time()))

<time.sleep>

time.sleep 함수는 루프 안에서 주로 사용되는데, 이 함수를 사용하면 일정한 시간 간격을 두고 루프를 실행할 수 있다.

import time
for i in range(10):
    print(i)
    time.sleep(1)

위 코드는 10초 간격으로 1부터 9까지의 숫자를 출력한다.
time.sleep 함수의 인수는 실수 형태를 쓸 수 있다. 즉 1이면 1초, 2이면 2초가 되는 것이다.

<math.gcd>

이 함수는 최대 공약수를 쉽게 구하기 위해 사용하는 함수이다.
(파이썬 3.5 버전부터 사용할 수 있다.)
다음 예시는 12, 42, 108의 최대 공약수를 구한 결과이다.

<math.lcm>

이 함수는 최소 공배수를 구하기 위해 사용하는 함수이다.
(파이썬 3.9 버전부터 사용할 수 있다.)

<random>

random은 난수를 발생시키는 모듈이다. 
random.random()은 0.0과 1.0 사이의 실수 중에서 난수 값을 리턴한다.
radom.randint(x, y)는 숫자 x와 y 사이의 정수 중에서 난수 값을 리턴한다.
random_pop 함수는 리스트의 요소 중에서 무작위로 하나를 선택하여 꺼낸 다음 그 값을 리턴한다.
random.choice 함수는 입력으로 받은 리스트에서 무작위로 하나를 선택하여 리턴한다.
random.sample 함수는 리스트의 항목을 무작위로 섞고 싶을 때 사용한다.

<itertools.zip_longest>

itertools.zip_longest(*iterables, fillvalue=None)

이 함수는 같은 개수의 자료형을 묶는 파이썬 내장 함수인 zip 함수와 똑같이 동작한다. 하지만 itertools.zip_longest() 함수는 전달한 반복 가능 객체의 길이가 서로 다르다면 긴 객체의 길이에 맞춰 fillvalue에 설정한 값을 짧은 객체에 채울 수 있다.

위 예시의 경우 students와 colors의 요소 개수가 다르므로 더 적은 colors의 개수만큼만 zip()으로 묶게 된다.
students의 요소 개수가 colors보다 많을 때 그만큼을 ‘핑크’로 채우려면 어떻게 해야 할까?
이럴 때 요소 개수가 많은 것을 기준으로 자료형을 묶는 itertools.zip_longest()를 사용하면 된다.
부족한 항목은 None으로 채우는데, 다음처럼 fillvalue로 값을 지정하면 None 대신 다른 값으로 채울 수 있다.

<iterpools.permutation>

itertools.permutations(iterable, r)

이 함수는 반복 가능 객체 중에서 r개를 선택한 순열을 이터레이터로 리턴하는 함수이다.
*이터레이터란 반복 가능한 객체를 의미한다.

<iterpools.combination>

itertools.combinations(iterable, r)

이 함수는 반복 가능한 객체 중에서 r개를 선택한 조합을 이터레이터로 리턴하는 함수이다.
이터레이터 객체를 루프를 이용하여 출력하면 아마 끝도 없이 출력될 것이다.
하지만 순환하여 출력하지 않고 이터레이터의 개수만 세려면 다음과 같이 하면 된다.

len(list(itertools.combinations(range( , ), )))

<functools.reduce>

functools.reduce(function, iterable)

이 함수는 함수를  반복 가능한 객체(iterable)의 요소에 차례대로(왼쪽에서 오른쪽으로) 누적 적용하여 이 객체를 하나의 값으로 줄이는 함수이다.
이 함수를 이용하여 최댓값을 구할 수도 있다.

<operator.itemgetter>

operator.itemgetter는 주로 sorted와 같은 함수의 key 매개변수에 적용하여 다양한 기준으로 정렬할 수 있도록 도와주는 모듈이다.

위 예시는 sorted 함수의 key 매개변수에 itemgetter()를 적용하여 리스트를 나이순으로 정렬한 결과이다.
itemgetter(1)은 members의 아이템인 튜플의 두 번째 요소를 기준으로 정렬하겠다는 의미이다.
*itemgetter(2)와 같이 사용한다면 성적순(A,B)으로 정렬될 것이다.

<shutil>

shutil은 파일을 복사(copy)하거나 이동(move)할 때 사용하는 모듈이다.

<glob>

특정 디렉터리에 있는 파일 이름 모두를 알아야 할 때 사용하는 모듈이다.
이 모듈은 디렉터리 안의 파일들을 읽어서 리턴하고,
몇 가지 메타 문자를 이용하여 원하는 파일만 읽어 들일 수도 있다.

<pickle>

객체의 형태를 그대로 유지하면서 파일에 저장하고 불러올 수 있게 하는 모듈이다.
pickle.dump 를 사용하면 딕셔너리 객체인 data를 그대로 파일에 저장할 수 있다.
pickle.load를 사용하면 pickle.dump 로 저장한 파일을 원래 있던 객체 상태 그대로 불러올 수 있다.
*어떤 자료형이든 저장하고 불러올 수 있다.

<os>

환경 변수나 디렉터리, 파일 등의 OS 자원을 제어할 수 있게 해 주는 모듈이다.

<os.environ>

os.environ은 제각기 다른 환경 변숫값 중 현재 시스템의 환경 변숫값을 리턴한다.
환경 변수에 대한 정보를 딕셔너리 형태로 구성된 environ 객체로 리턴하는데,
이렇게 리턴받은 객체는 다음과 같이 호출하여 사용할 수 있다.

os.environ[ ]

<os.chdir>

디렉터리 위치를 다음과 같이 변경할 수 있다.

os.chdir("C:\WINDOWS")

<os.getcwd>

현재 자신의 디렉터리 위치를 리턴한다.

os.getcwd()
'C:\WINDOWS'

<os.system>

시스템 자체의 프로그램이나 기타 명령어를 파이썬에서 호출할 수도 있다.

os.system("명령어")

<os.popen>

시스템 명령어를 실행한 결괏값을 읽기 모드 형태의 파일 객체로 리턴한다.

f = os.popen("명령어")

읽어 들인 파일 객체의 내용을 보기 위해서는 다음과 같은 코드를 사용한다.

print(f.read())

이 외에도 유용한 os 관련 함수에는 os.mkdir, os.rmdir, os.remove, os.rename이 있다.


📌느낀점

 다양한 함수 툴(tool)을 본격적으로 배워 본 시간 같아 뜻깊었습니다.
동시에 여러가지 개념들을 다루다 보니 복습이 필요할 것 같습니다.



  • 작성자: 김민정
  • 작성일: 4/1
  • 진도: [5-6] zipfile ~ [5-7]

📌zipfile

zipfile은 여러 개의 파일을 zip형식으로 합치거나 해제할 때 사용하는 모듈으로, zipfile.ZipFile()을 사용한다.
zip형식으로 합칠 때에는 zipfile.ZipFile()과 함께 write() 함수를 통해 개별 파일을 추가할 수 있고,
zip형식을 해제할 때에는 extractall() 함수를 사용한다.

import zipfile

with zipfile.ZipFile('mytext.zip', 'w') as myzip:
    myzip.write('a.txt')
    myzip.write('b.txt')
    myzip.write('c.txt')

with zipfile.ZipFile('mytext.zip') as myzip:
    myzip.extractall()

📌파일 압축

파일을 압축하여 묶을 때에는 compression, compresslevel 을 사용한다.

with zipfile.ZipFile('mytext.zip', 'w', compression=zipfile.ZIP_LZMA, compresslevel=9) as myzip:

compression에는 4가지 종류가 있다.
1. ZIP_STORED: 압축하지 않고 zip으로 묶기만 한다. (따라서 속도가 빠르다.)
2. ZIP_DEFLATED: 가장 일반적인 압축으로 호환성이 좋고, 압축률은 낮으나 속도가 비교적 빠른 편이다.
3. ZIP_BZIP2: 압축률이 높고 속도가 느린 압축이다.
4. ZIP_LZMA: 압축률이 높고 속도가 느린 압축이다. (7zip과 동일한 알고리즘이다.)
compressionlevel은 압축된 정도를 의미하는 숫자값인데, 1~9 중으로 표현하며
숫자가 작을수록 속도가 빠르지만 압축률이 낮다. (압축률과 속도는 반비례한다는 것을 알 수 있다.)

📌threading

컴퓨터에서 동작하고 있는 프로그램은 프로세스(process)라고 한다.
보통 1개의 프로세스는 1가지 일만 하지만 스레드를 사용하면 한 프로세스 안에서 여러 일을 동시에 수행할 수 있다.
예를 들어, 수행하는 데에 n초가 걸리는 함수가 있다고 하자.
a번 반복 수행하려면 n*a만큼의 시간이 걸리지만 스레드를 사용하면 동시에 수행할 수 있으므로 이 시간을 줄일 수 있다.
threading.Thread를 사용하여 스레드 객체를 만들어 이용할 수 있다.
이때 스레드의 join함수를 사용하지 않으면 스레드의 결과가 출력된 이후에도 프로그램이 정상적으로 종료되지 않는 문제가 있다. join함수는 해당 스레드가 종료될 때까지 기다리게 하는 함수이다.

📌tempfile

파일을 임시로 만들어서 사용할 때 유용한 모듈이 바로 tempfile이다. tempfile.mkstemp()를 이용하면 중복되지 않는 임시 파일의 이름을 무작위로 만들어서 리턴할 수 있다.
tempfile.TemporaryFile() 은 임시 저장 공간으로 사용할 파일 객체를 리턴한다.
이 파일은 기본적으로 바이너리 쓰기 모드 (wb)를 갖는다. f.close()가 호출되면 이 파일은 자동으로 삭제된다.

📌traceback

traceback은 프로그램을 실행하던 중 발생한 오류를 추적할 때 사용할 수 있는 모듈이다.

main() 함수가 시작되면 b()함수를 호출하고 b()함수에서 다시 a()함수를 호출하여 1을 0으로 나누기 때문에 오류가 발생하여 ‘오류가 발생했습니다.’라는 메세지를 출력한 것이다.

📌json

JSON데이터를 쉽게 처리하고자 할 때 json모듈을 사용한다.

{
    "name": "김민정",
    "birth": "0223",
    "age": 21
}

myinfo.json 파일


JSON 데이터를 딕셔너리 자료형으로 바꾸어 파이썬에서 처리하려면 json.load(파일객체)를 사용하면 된다.

>>> import json
>>> with open('myinfo.json') as f:
...     data = json.load(f)
... 
>>> type(data)
<class 'dict'>
>>> data
{'name': '김민정', 'birth': '0223', 'age': 21}


이처럼 load() 함수는 읽은 데이터를 딕셔너리 자료형으로 리턴하는 함수이다.
이와 반대로 딕셔너리 자료형을 JSON 파일로 생성할 때는 json.dump(딕셔너리, 파일_객체)를 사용하면 된다.

📌urllib

urllib은 URL을 읽고 분석할 때 사용하는 모듈이다.
브라우저로 위키독스의 특정 페이지를 읽으려면 다음과 같이 요청하면 된다.

https://wikidocs.net/페이지_번호

위키독스의 특정 페이지를 .html 파일로 저장하면 오프라인에서도 읽을 수 있다.

#urllib_test.py
import urllib.request
def get_wikidocs(page):
	resource='https://wikidocs.net/{}'.format(page)
    with urllib.request.urlopen(resource) as s:
    	with open('wikidocs_%s.html' % page, 'wb') as f:
        	f.write(s.read())

📌webbrowser

webbrowser는 파이썬 프로그램에서 시스템 브라우저를 호출할 때 사용하는 모듈이다.
open_new() 함수를 이용하면 파이썬으로 웹페이지를 새 창으로 열 수 있다.

import webbrowser
webbrowser.open_new('http://python.org')

이미 열려있는 브라우저로 원하는 사이트를 열고 싶다면 open_new()가 아닌 open()을 사용한다.

webbrowser.open('http://python.org')

📌외부 라이브러리

파이썬 설치 시 기본으로 설치되는 라이브러리를 ‘파이썬 표준 라이브러리’라고 한다.
외부 라이브러리는 표준 라이브러리가 아니므로 pip 도구를 이용하여 설치한 후 사용할 수 있다.

<pip>

파이썬 모듈이나 패키지를 쉽게 설치할 수 있도록 도와주는 도구가 pip이다.
pip install
파이썬 패키지를 설치할 때  PyPI를 이용해도 되지만 pip를 이용하면 더 간편하다. 명령어는 pip install SomePackage이다.
pip uninstall
설치한 패키지를 삭제하고 싶다면 다음 명령어로 삭제할 수 있다. pip uninstall SomePackage이다.
특정 버전을 지정하여 설치하려면 설치 명령어 뒤에 ==버전 을 덧붙이면 된다.
(설치할 버전을 지정하지 않으면 기본값으로 최신 버전이 설치된다.)
기존에 설치되어 있던 패키지를 최신 버전으로 업그레이드하려면 pip install 명령어 뒤에
—upgrade SomePackage를 덧붙이면 된다. 
설치된 패키지를 확인하는 방법도 있다. pip list 명령어는 설치된 패키지 목록을 출력한다.
이때 패키지의 버전도 함께 확인할 수 있다.

<Faker>

외부 라이브러리 Faker는 테스트용 가짜 데이터를 생성할 때 사용하는 라이브러리이다.
Faker 라이브러리는 pip를 이용하여 설치한다.

C:\> pip install Faker

Faker는 name, address, postcode 등등 다양한 항목을 제공하기 때문에 활용 범위가 넓다.
아래는 경희대학교의 주

>>> fake.address()
'경희대로26, 동대문구, 서울'

<sympy>

 
외부 라이브러리 sympy는 방정식 기호를 사용하게 해 주는 라이브러리이다.
(마찬가지로 pip를 이용한다.)

C:\> pip install sympy

(sympy 모듈을 이용하려면 fractions 모듈 또한 필요하다.)
방정식에 사용하는 미지수를 나타내는 기호를 생성할 때 sympy.symblos() 를 사용한다.
(여러 개의 기호가 필요할 때도 동일한 방법으로 명령어를 한 번만 사용하여 생성하면 된다.)


📌느낀점

이번 스터디 내용은 너무 어려워서 스스로 적용시키는 데에 한계가 있었지만 동시에 더 열심히 공부해야겠다고 다짐하는 계기가 된 것 같다. 복습을 열심히 해야겠다!