1.  객체

🚀   개발을 하다 보면 정수나 실수 또는 문자열 등 기본적인 자료형으로 표현하기 힘든 것들이 존재
         ➡️  예를 들어 어떤 게시글을 파이썬으로 표현을 한다면 [게시글 번호, 제목, 작성자, 비밀번호, 내용, 최초작성일자, 최종수정일자, 조회수]가 필요한데 이를 손쉽게 관리 하려면 8개의 항목을 하나의 이름을 가진 객체 object로 만들어서 사용

 


2. 클래스

🚀  클래스 class를 한 마디로 정의하면 객체를 만드는 도구
🚀  하나의 클래스를 만들어 두면 그 클래스를 통해서 (동일한 구조를 가진) 여러 개의 객체를 만들수 있다
        ➡️  같은 클래스로 만든 객체라 하더라도 객체들은 서로 다른 값을 가질수 있음
        ➡️  인스턴스 instance 역시 클래스를 이용해서 생성한 객체를 가르키는 용어

 

    💡  객체와 인스턴스의 미묘한 차이
            a. 와플머신 클래스로 만든 와플은 객체 object
            b. 와플은 와플머신 클래스의 인스턴스 instance


1) 클래스의 구성

👾  클래스의 기본 구성
    -  객체를 만들어내는 클래스는 객체가 가져야 할 값과 기능을 가지고 있어야 함
         ▶️  값은 변수, 기능은 함수
    -  클래스를 구성하는 변수는  a. 클래스를 기반으로 생성된 모든 인스턴스들이 공유하는 변수인 '클래스 변수'
                                                    b. 모든 인스턴스들이 개별적으로 가지는 변수인 '인스턴스 변수'로 분리됨
    -  클래스를 구성하는 함수는 메소드 method라고 하고
         a) 클래스 메소드 b) 정적 메소드 c) 인스턴스 메소드로 분리


2) 클래스 정의방법

👾 class 키워드로 클래스를 정의
👾 클래스 이름은 Upper Camel Case 규칙을 따름
👾
파이썬은 변수나 함수의 이름을 네이밍할 때 언더바(_)를 이용해 단어를 연결하는 Snake Case 방식을 사용하지만

     클래스는 Upper Camel Case 규칙을 따름
      ex. print + member : printmember 1) print_member 2) printMember 3) PrintMember

# 클래스는 다음과 같은 형식으로 정의
class 클래스 :
    본문

3. 객체 생성

# 클래스가 정의되었다면 다음과 같은 형식으로 객체를 생성
객체 = 클래스()

# 2개의 객체를 만들고 싶으면
객체1 = 클래스()
객체2 = 클래스()

# 클래스 정의와 객체 생성
class WaffleMachine : # WaffleMachine이라는 클래스 정의
    pass  # 내부코드를 작성하지 않을 때 쓰임

waffle1 = WaffleMachine()  # WaffleMachine 이라는 클래스를 이용해 waffle이라는 객체 생성
waffle2 = WaffleMachine()

print(waffle1)  # <__main__.WaffleMachine object at 0x102beee60>
# 메모리의 0x102beee60번지에 저장된 WaffleMachine의 객체라는 의미
print(waffle2)

4. 인스턴스 변수와 인스턴스 메소드

🚀  인스턴스 변수란 클래스를 기반으로 만들어지는 모든 인스턴스들이 각각 따로 저장하는 변수
      ⚡️ 모든 인스턴스 변수는 self라는 키워드를 앞에 붙여줌
🚀  인스턴스 메소드란 인스턴스 변수를 사용하는 메소드
      ⚡️ 인스턴스 메소드는 반드시 첫 번째 매개변수로 self를 추가해야 함

class Person :  # Person 클래스를 정의
    # 첫 번째 매개변수가 self이므로 인스턴스 메소드
    # 모든 인스턴스는 who_am_i() 메소드를 호출할 수 있음
    # 매개변수 self에는 메서드를 호출하는 인스턴스가 전달
    # self를 제외한 나머지 매개변수에 실제로 사용될 데이터가 전달
    def who_am_i(self, name, age, tel, address):
        # 인스턴스 변수 = 매개변수. 모든 인스턴스 변수는 최초에 값이 대입되는 시점에 알아서 생성.
        self.name = name
        self.age = age
        self.tel = tel
        self.address = address

boy = Person()  # 인스턴스 boy가 생성. 클래스의 생성자가 호출
#print(boy.name)  # 'Person' object has no attribute 'name'
boy.who_am_i('john', 15, '123-1234', 'toronto')  #인스턴스 메소드 호출
print(boy.name)  # john
print(boy.age)  # 15
print(boy.tel)  # 123-1234
print(boy.address)  # toronto

# 클래스에 없는 속성도 추가가 가능함. 다른 언어의 객체와는 다른 방식.
boy.email = 'test@test.com'
print(boy.email)  # test@test.com

 

 


 

5. 생성자  constructor

 

🚀  클래스 이름과 같은 함수를 생성자라고 한다.  

🚀  값을 가진 인스턴스를 생성하기 위해 생성자를 이용
🚀  생성자는 인스턴스를 생성할 때 자동으로 호출되는 특별한 메소드

 

    ⚡️  모든 클래스는 __init__() 이라는 이름을 가진 함수를 가지고 있음
            ➡️  인스턴스가 생성될 때 자동으로 호출되기 때문에 인스턴스 변수의 초기화 용도로 사용

class Candy:
    def __init__(self, shape, color):
        print('실행이 될까?')
        self.shape = shape
        self.color = color

satang = Candy('circle', 'brown')
print(satang.color) 
# 실행이 될까?
# brown

 


 

6. 소멸자  destructor

🚀  인스턴스가 생성될 때 자동으로 호출되는 생성자와 마찬가지로 인스턴스가 소멸될 때 자동으로 호출되는 메소드
🚀  소멸자는 __del__()

class Sample:
    def __del__(self):
        print('인스턴스가 소멸됩니다')

sample = Sample()

del sample  # 인스턴스가 소멸됩니다


# 매직 메서드 샘플
class Sample:
    def __int__(self):
        pass

    def __len__(self):
        return 6

    def __str__(self):
        return 'what?'

li = [1, 2, 3]
print(len(li))  # 3

sample = Sample()
print(len(sample))  # 6
print(sample)  # what?

 

7.  메소드  method

🚀  클래스가 가지고 있는 함수를 말한다.

🚀  파이썬 프로그래밍에서는 멤버 함수(member funcion) 혹은 인스턴스 함수(instance function) 등의 용어를 더 많이 사용함

class 클래스 이름:
    def 메소드 이름(self, 추가적인 매개변수):
        pass

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 '혼자 공부하는 파이썬' ]


 

1. 모듈 만들기

 

# test_module.py 파일
PI = 3.141592

def number_input():
    output = input("숫자 입력 >>> ")
    return float(output)

def get_circumference(radius):
    return 2 * PI * radius

def get_circle_area(radius):
    return PI * radius * radius
# test.py 파일
import test_module as test

radius = test.number_input()
print(test.get_circumference(radius))
print(test.get_circle_area(radius))

 


 

2.  __name__ =="__main__"

 

📁  프로그램의 진입점을 엔트리 포인트 entry point 또는 메인 main 이라고 부른다

      ➡️  엔트리 포인트 또는 메인 내부에서의 __name__ 은 "__main__"

📁  모듈 내부에서 __name__ 을 출력하면 모듈의 이름을 나타낸다.

# 엔트리 포인트 확인하는 모듈
PI = 3.141592

def number_input():
    output = input("숫자 입력 >>> ")
    return float(output)

def get_circumference(radius):
    return 2 * PI * radius

def get_circle_area(radius):
    return PI * radius * radius

# 현재 파일이 엔트리 포인트인지 확인하고, 엔트리 포인트일 때만 실행
if __name__ == '__main__':
    print('get_circumference(10):', get_circumference(10))
    print('get_circle_area(10)', get_circle_area(10))

 


 

3. __init__.py 파일

📁  해당 폴더가 패키지임을 알려주고, 패키지와 관련된 초기화 처리를 하는 파일

       ➡️  패키지 폴더 내부에 __init__.py 파일을 생성

📁  __all__ 이라는 이름의 리스트를 파일안에 만드는데, 이 리스트에 지정한 모듈들이 from<패키지이름> import * 를 할 때 전부 읽어 들여진다.

# "from <모듈이름> import *"로
# 모듈을 읽어 들일 때 가져올 모듈
__all__ = [사용시 읽어 들일 모듈의 목록]

 

 

 

 

 

[ 내용 참고 : 책 '혼자 공부하는 파이썬' ]


 

1.  외부 모듈의 이용

📁  외부 모듈은 다른 사람들이 만들어 배포하는 모듈을 말함

 

1) 패키지

    👾  모듈의 상위 개념으로 모듈의 집합을 의미
    👾  파이썬에서 기본적으로 제공하지 않더라도 외부에서 만들어진 패키지를 이용하면 패키지에 포함된 모듈을 사용할 수 있음


2) 패키지 관리자

    👾  외부 모듈을 사용하기 위해서는 우선 모듈이 포함된 패키지를 추가로 설치
    👾  pip라고 불리는 패키지 관리자를 사용해서 패키지를 추가, 삭제


3) 패키지 설치

💡  보통 관심있는 분야와 관련된 모듈을 검색해서 설치

       📌  맥os 에서는 터미널에 입력하여 설치

 pip install package


    👾  numpy 패키지수치해석과 통계에서 많이 사용

import numpy as np
print(np.sum([1, 2, 3, 4, 5]))  # 15

 


   

    👾  Beautiful Soup는 파이썬 웹 페이지 분석 모듈

# Beautiful Soup 모듈로 날씨 가져오기
from urllib import request
from bs4 import BeautifulSoup

# urlopen() 함수로 기상청의 전국 날씨 읽기
target = request.urlopen("http://www.kma.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108")

# 웹페이지 분석
soup = BeautifulSoup(target, "html.parser")

# location 태그 찾기
for location in soup.select("location"):
    # 내부 city, wf, tmn, tmx 태그를 찾아 출력
    print("도시:", location.select_one("city").string)
    print("날씨:", location.select_one("wf).string)
    print("최저기온:", location.select_one("tmn").string)
    print("최고기온:", location.select_one("tmx").string)
    print()
    
'''
도시: 서울
날씨: 구름많음
최저기온: 3
최고기온: 9

도시: 인천
날씨: 구름많음
최저기온: 2
최고기온: 8

도시: 수원
날씨: 구름많음
최저기온: 2
최고기온: 10
...생략...
'''

 

  📌  urllib는 URL 작업을 위한 여러 모듈을 모은 패키지 

  📌  태그를 여러개 선택할 때 select(), 한 개 선택할 때 select_one() 사용하여 값 추출

 


 

    👾  Django는 다양한 기능을 제공하는 웹 개발 프레임워크, Flask는 작은 기능만을 제공하는 웹 개발 프레임워크

pip install flask
from flask import Flask
app = Flask(__name__)

@app.rout("/")
def hello():
    return "<h1>Hello World!</h1>"
# @app.route() 는 데코레이터

 

# 맥 os 에서 Flask 코드 실행 방법
export FLASK_APP=파일 이름.py
flask run
# 터미널에 입력

 

    ⚡️  프로그램 종료할 때는 Ctrl + C


4) 패키지 삭제

pip uninstall package
ex. pip uninstall numpy

 


 

2. 라이브러리와 프레임워크

📁  라이브러리(library) : 정상적인 제어를 하는 모듈

📁  프레임워크(framework) : 제어 역전이 발생하는 모듈

    

1) 라이브러리

   - 개발자가 모듈의 기능을 호출하는 형태의 모듈

from math import sin, cos, tan, floor, ceil

 

2) 프레임워크

    - 모듈이 개발자가 작성한 코드를 실행하는 형태의 모듈 

         ex. Flask 모듈이 제공하는 명령어를 실행하면  Flask가 내부적으로 서버를 실행한 뒤 지정한 파일을 읽어 들여

               적절한 상황에 스스로 실행하게 됨

    - 개발자가 만든 함수를 모듈이 실행하는 것은 제어가 역전된 것

 


 

3. 데코레이터

 

1) 함수 데코레이터

⚡️  함수에 사용하는 데코레이터

       ➡️  대상 함수의 앞뒤에 꾸밀 부가적인 내용 혹은 반복할 내용을 데코레이터로 정의해서 손쉽게 사용할 수 있도록 한 것

# 함수 데코레이터 생성
def test(function):
    def wrapper():
        print("인사가 시작되었습니다.")
        function()
        print("인사가 종료되었습니다.")
    return wrapper
    
# 데코레이터를 붙여 함수를 만든다
@test
def hello():
    print("hello")
    
# 함수를 호출
hello()

'''
인사가 시작되었습니다.
hello
인사가 종료되었습니다.
'''

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 '혼자 공부하는 파이썬' ]


 

1. 모듈  module

📁  여러 변수와 함수를 가지고 있는 집합체

📁  파이썬에 기본적으로 내장되어 있는 모듈을 '표준 모듈', 다른 사람들이 만들어 공개한 모듈을 '외부 모듈'

 


 

1) 모듈의 사용

👾 반드시 같은 디렉토리에 있어야 함
👾 모듈에 저장된 함수를 사용하는 방법
      A. 모듈 전체를 가져오는 방법
          - 모듈에 저장된 '모든' 클래스나 함수를 사용하고자 할 때
             ex. import 모듈

# import 모듈이름으로 불러옴

import converter

miles = converter.kilometer_to_miles(150)  # 모듈.함수() 형식으로 호출
print(f'150km={miles}miles')  # 150km=93.20565miles

pounds = converter.gram_to_pounds(1000)
print(f'1000g={pounds}pounds')  # 1000g=2.20462pounds

 

 

      B. 모듈에 포함된 함수 중에서 특정 함수만 골라서 가져오는 방법
            ex. from 모듈 import 함수
                   from 모듈 import 함수1, 함수2
                   from 모듈 import *

from converter import kilometer_to_miles  # 모듈은 가져오지 않고 특정 함수만 가져옴

miles = kilometer_to_miles(150)  # 모듈명을 명시하지 않고 사용
print(f'150km={miles}miles')  # 150km=93.20565miles

print()
from converter import *  # 모듈은 가져오지 않고 모듈의 모든 함수 가져옴

miles = kilometer_to_miles(150)  # 모듈명을 명시하지 않고 사용
print(f'150km={miles}miles')

pounds = gram_to_pounds(1000)
print(f'1000g={pounds}pounds')  # 모듈명을 명시하지 않고 사용

 


 

2) 별명 사용

👾  모듈이나 함수를 import 하는 경우에 원래 이름 대신 별명 alias를 지정하고 사용
👾  모듈이나 함수의 이름이 긴 경우에 주로 짧은 별명을 지정하고 긴 본래 이름 대신 사용
👾  별명을 지정할 때는 as 키워드를 사용

import converter as cvt  # converter 모듈에 cvt라는 별명을 지정

miles = cvt.kilometer_to_miles(150)  # 별명을 이용해서 함수 사용
print(f'150km={miles}miles')

pounds = cvt.gram_to_pounds(1000)
print(f'1000g={pounds}pounds')

print()
from converter import kilometer_to_miles as k_to_m  # 함수에도 별명을 지정 가능

miles = k_to_m(150)  # 함수 이름 대신 별명을 사용
print(f'150km={miles}miles')

 


 

2. math 모듈

📁  말 그대로 수학과 관련된 기능을 가지고 있다

변수 또는 함수 설명
원주율 pi 더 정확한 파이 값을 사용하기 위해
ceil() & floor() 전달된 값을 정수로 올림 처리하거나 내림 처리
trunc() 전달된 값을 정수로 절사, 양수를 처리할 때는 차이가 없지만
음수를 처리할 때는 결과의 차이가 있다
sqrt() 제곱근 구함
pow() 제곱을 구함

 

import math  # import 후 사용

# 1) 원주율 pi
print(math.pi)  # 3.141592653589793

# 2) ceil() 함수와 floor() 함수
print(math.ceil(1.1))  # 2 / 정수로 올림 처리
print(math.floor(1.9))  # 1 / 정수로 내림 처리

# 3) trunc() 함수
print(math.trunc(-1.9))  # -1 / 절사이므로 소수점 이하를 잘라버림
print(math.floor(-1.9))  # -2 / 내림이므로 -1.9 보다 작은 정수로 내림

# 4) sqrt() 함수
print(math.sqrt(25))  # 5.0 / 루트 25를 의미

 

3. random 모듈

📁  난수 random number 를 생성하는 모듈
📁  난수를 통해서 간단한 게임을 제작할 수 있고 확률 처리도 할 수 있다

변수 또는 함수 설명
randint() 전달하는 두 인수 사이의 정수를 임의로 생성
randrange() range() 함수는 특정범위의 정숫값들을 모두 생성할 수 있지만,
randrange() 함수는 그 특정 범위에 속한 정수중 하나만 임의로 생성
random() 0이상 1미만 범위에서 임의의 실수를 생성
0이상 1미만 범위를 백분율로 환산하면 0%이상 100%미만이기 때문에 확률을 처리할 때도 사용
choice(list) 전달된 시퀀스 자료형에 속한 요소 중에서 하나를 임의로 반환
sample(list, k=<숫자>) 전달된 시퀀스 자료형에 속한 요소 중 지정된 개수의 요소를 임의로 반환
반환 결과는 리스트 list 자료형이며 중복없이 임의의 요소가 선택
shuffle(list) 전달된 시퀀스 자료형에 속한 요소의 순서를 임의로 조정하여 다시 재배치하는 함수
호출하면 실제 전달된 시퀀스 자료형의 순서가 재배치

 

import random

# 1) randint() 함수
print(random.randint(1,10))  # 1이상 10이하의 정수

# 2) randrange() 함수
print(random.randrange(10))  # 0이상 10미만의 정수
print(random.randrange(1,10))  # 1이상 10미만의 정수
print(random.randrange(1,10,2))  # 1이상 10미만의 홀수

# 3) random() 함수
print(random.random())  # 0.1859815803780659

# 50% 확률로 '안녕하세요' 출력
if random.random() < 0.5:
    print('안녕하세요')

rand = random.randint(1,2)
print(rand)
if rand == 1:
    print('안녕하세요')

# 4) choice() 함수
seasons = ['spring', 'summer', 'fall', 'winter']
print(random.choice(seasons))  # fall

idx = random.randint(0, len(seasons) - 1)
print(seasons[idx])

# 5) sample() 함수
print(random.sample(range(1, 46), 6))  # [36, 4, 14, 35, 12, 16]

seasons = ['spring', 'summer', 'fall', 'winter']
print(random.sample(seasons, 3))
seasons = ['summer', 'summer', 'summer', 'winter']
print(random.sample(seasons, 3))

# 6) shuffle() 함수
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print(my_list)  # [4, 2, 3, 1, 5]

 


 

4. sys 모듈

📁  시스템과 관련된 정보를 가지고 있는 모듈

📁  명령 매개변수를 받을 때 많이 사용

import sys

# 명령 매개변수 출력
print(sys.argv)  # ['/Users/Desktop/pycharm/pythonProject/book/1.py']
print("----")

# 컴퓨터 환경과 관련된 정보 출력
print("copyright:", sys.copyright)  
print("----")
print("version:", sys.version)
'''
copyright: Copyright (c) 2001-2023 Python Software Foundation.
All Rights Reserved.
... 생략 ...
----
version: 3.10.13 (main, Sep 11 2023, 08:16:02) [Clang 14.0.6 ]
'''

# 프로그램 강제 종료
sys.exit()

 


 

5. os 모듈

📁  운영체제와 관련된 기능을 가진 모듈

import os

# 기본 정보 출력
print("현재 운영체제:", os.name)
print("현재 폴더:", os.getcwd())
print("현재 폴더 내부의 요소:", os.listdir())
'''
현재 운영체제: posix
현재 폴더: /Users/Desktop/pycharm/pythonProject/book
현재 폴더 내부의 요소: ['1.py']
'''
# 폴더 만들고 제거(폴더가 비어있을 때만 가능)
os.mkdir("hello")
os.rmdir("hello")

# 파일 생성하고 파일 이름 변경
with open("original.txt", "w") as file:
    file.write("hello")
os.rename("original.txt", "new.txt")

# 파일 제거
os.remove("new.txt")

# 시스템 명령어 실행
os.system("dir")

 


 

6. datetime 모듈

📁  날짜와 시간 데이터를 처리할 때 사용

변수 또는 함수 설명
now() 시스템의 현재 날짜와 시간을 반환
date() 특정 날짜를 반환
time() 특정 시간을 반환
날짜/시간 관련 필드값 특정 날짜에 원하는 데이터만 추출하고자 할때 이용
timedelta() 날짜 / 시간 데이터의 연산을 위하여 사용
total_seconds() 어떤 기간에 포함된 총 시간의 초 seconds 로 반환

 

import datetime

# 1) now() 메소드
present = datetime.datetime.now()
print(present)

# 2) date() 함수
birthday = datetime.date(2014, 8, 25)
print(birthday)  # 2014-08-25

# 3) time() 함수
wake = datetime.time(10, 48, 0)
print(wake)  # 10:48:00

# 4) 날짜 / 시간 관련 필드값
today = datetime.datetime.now()
print(today.year)  # 년도
print(today.month)  # 월
print(today.day)  # 일
print(today.hour)  # 시
print(today.minute)  # 분
print(today.second)  # 초

# 5) timedelta() 함수
# 1주 : timedelta(weeks=1)
# 1일 : timedelta(days=1)
# 1시간 : timedelta(hours=1)
# 1분 : timedelta(minutes=1)
# 1초 : timedelta(seconds=1)

today = datetime.datetime.now()
yesterday = today - datetime.timedelta(days=1)  # 어제 구함
tomorrow = today + datetime.timedelta(days=1)  # 내일 구함
print(yesterday)
print(tomorrow)

# 6) total_seconds() 메소드
date1 = datetime.date(2020, 8, 25)
date2 = datetime.date(2020, 8, 26)
print(date2 - date1)  # 1 day, 0:00:00
print((date2 - date1).total_seconds())  # 86400.0 = 60초 * 60분 * 24시간

 


 

7. time 모듈

📁  시간과 관련된 기능 처리

변수 또는 함수 설명
time() 1970년 1월 1일 0시 0분 0초 부터 현재까지 경과된 시간 timestamp을 반환
소수점 이하는 마이크로 초를 의미
ctime() 인수로 전달된 시간 timestamp을 형식에 갖춰 반환
strftime() 인수로 전달된 날짜와 지시자를 이용하여 형식을 갖춘 날짜 데이터가 문자열로 반환
sleep() 인수로 전달된 초 second 만큼 시스템을 일시 정지

 

import time

# 1) time() 함수
print(time.time())  # 1645240996.2733545

# 2) ctime() 함수
print(time.ctime(time.time()))  # Sat Feb 19 12:23:16 2022

# 3) strftime() 함수
# 년 : %y : 2자리 날짜로 표시
# 년 : %Y : 4자리 날짜로 표시
# 월 : %m : 2자리 숫자로 표시 (01 ~ 12)
# 월 : %b : 3자리 영문으로 표시 (Jan ~ Dec)
# 월 : %B : 전체 영문으로 표시 (January ~ December)
# 일 : %d : 2자리 숫자로 표시 (01 ~ 31)
# 요일 : %a : 3자리 영문으로 표시 (Sun ~ Sat)
# 요일 : %A : 전체 영문으로 표시 (Sunday ~ Saturdy)
# 시 : %l : 12시간제로 표시 (01 ~ 12)
# 시 : %H : 24시간제로 표시 (00 ~ 23)
# 분 : %M : 2시간제로 표시 (00 ~ 59)
# 초 : %S : 2시간제로 표시 (00 ~ 59)
# 오전 / 오후 : %p : AM 또는 PM
print(time.strftime('%Y-%m-%d %H:%M:%S'))

# 4) sleep() 함수
time.sleep(1)

 


 

8.  urllib 모듈

📁  URL을 다루는 라이브러리

📁  URL : Uniform Rssource Locator, 네트워크의 자원이 어디에 위치하는지 확인할 때 사용하는 것

       ▶️  웹 브라우저의 주소창에 입력하는 주소

from urllib import request

# urlopen() 함수로 구글 메인페이지를 읽습니다
target = request.urlopen("https://google.com")
output = target.read()

# 출력합니다
print(output)

'''
b'<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" 
lang="ko"><head><meta content="text/html; charset=UTF-8" 
... 생략 ...
'''

 

 

 

 

 

[ 내용 참고 : IT 학원 강의 및 책 '혼자 공부하는 파이썬' ]


 

1. 튜플  tuple

 

📁  리스트와 비슷한 자료형이나 한번 결정된 요소를 바꿀 수 없다는 것이 다르다.

       ➡️  이미 저장된 값 이외에는 추가, 수정, 삭제가 불가능

📁  리스트와 마찬가지로 각 요소를 구분하기 위한 인덱스가 부여되고 슬라이싱도 지원
📁  튜플은 소괄호() 나 tuple() 함수를 이용해서 생성
📁  값들을 콤마(,)로 분리하여 전달하면 자동으로 튜플이 생성

t1 = (1,2,3)
print(t1)  # (1,2,3)

# 괄호 없이 사용 가능
t2 = 1,2,3
print(t2)  #(1,2,3)

def sample():
   return (1,2)

print(sample())  #(1, 2)
# 값이 2개 반환된 것이 아니라 튜플을 자동으로 적용해서 반환함

# 리스트를 튜플로 변경
t3 = tuple([100, 3.14, 'hello'])
print(t3)  # (100, 3.14, 'hello')

# 값을 1개만 보관하는 튜플을 생성할 경우에는 값과 콤마(,)를 반드시 함께 작성
t4 = (100)
print(t4)  # 100  / 값으로 인식
print(type(t4))  # <class 'int'>

t5 = (100, )
print(t5)  # (100, ) / 튜플로 인식
print(type(t5))  # <class 'tuple'>

# 값을 swap 교환
a = 10
b = 20
print(a, b)  # 10 20
a, b = b, a  # (a, b) = (b, a)
print(a, b)  # 20 10

a, b = 100, '홍길동'
print(a)  # 100
print(b)  # 홍길동

 

 


 

2. 람다  lambda

 

📁  함수를 짧게 쓸 수 있는 파이썬의 문법

 

1)  콜백 함수  callback function

    ⚡️  함수의 매개변수에 사용하는 함수

# 매개변수로 받은 함수를 10번 호출하는 함수
def call_10_times(func):
    for i in range(10):
        func()
        
# 간단한 출력하는 함수
def print_hello():
    print("안녕하세요")
    
# 조합하기
call_10_times(print_hello)
# -> print_hello() 함수를 10번 실행

 


 

2) filter() 함수와 map() 함수

⚡️  함수를 매개변수로 사용하는 대표적인 표준함수

⚡️  map() 함수는 리스트의 요소를 함수에 넣고 리턴된 값으로 새로운 리스트를 구성

⚡️  filter() 함수는 리스트의 요소를 함수에 넣고 리턴된 값이 True인 것으로, 새로운 리스트를 구성

# map()
map(함수, 리스트)

# filter()
filter(함수, 리스트)
def power(item):
    return item * item
def under_3(item):
    return item < 3

list_input_a = [1, 2, 3, 4, 5]

# map() 사용
output_a = map(power, list_input_a)
print(output_a)  # <map object at 0x104c228f0>
print(list(output_a))  # [1, 4, 9, 16, 25]

# filter() 사용
output_b = filter(under_3, list_input_a)
print(output_b)  # <filter object at 0x104c22800>
print(list(output_b))  # [1, 2]

 

  👾  <map object> 와 <filter object> 를 제너레이터라고 부른다.

 


 

3) 람다의 개념

⚡️  간단한 함수를 쉽게 선언하는 방법을 뜻함

# 기본형식
lambda 매개변수: 리턴값
list_input_a = [1, 2, 3, 4, 5]

# map() 함수
output_a = map(lambda x: x * x, list_input_a)
print(output_a)  # <map object at 0x102d12860>
print(list(output_a))  # [1, 4, 9, 16, 25]

# filter() 함수
output_b = filter(lambda x: x < 3, list_input_a)
print(output_b)  # <filter object at 0x102d61810>
print(list(output_b))  # [1, 2]

 


 

3. 제너레이터  generator

📁  이터레이터를 직접 만들 때 사용하는 코드

📁  함수 내부에 yield 키워드를 사용하면 해당 함수는 제너레이터 함수가 된다.

📁  일반 함수와 달리 함수를 호출해도 함수 내부의 코드가 실행되지 않는다.

 

def test():
    print("함수가 호출되었습니다")
    yield "test"
    
print("A 지점 통과")  # A 지점 통과
test()

print("B 지점 통과")  # B 지점 통과
test()
print(test())  # <generator object test at 0x104ceda10>

 

  📌  위 예제에서 test()함수는 출력되지 않고, 제너레이터를 리턴한다.

  📌  제너레이터 객체는 next() 함수를 사용해 함수 내부 코드를 실행한다.

          ➡️  이때 yield 키워드 부분까지만 실행하며, next() 함수의 리턴값으로 yield 키워드 뒤에 입력한 값이 출력된다

 

def test():
    print("A 지점 통과")
    yield 1
    print("B 지점 통과")
    yield 2
    print("C 지점 통과")
  
output = test()

# next() 함수 호출
print("D 지점 통과")
a = next(output)
print(a)
print("E 지점 통과")
b = next(output)
print(b)
print("F 지점 통과")
c = next(output)
print(c)

next(output)

 

 

 

📌  next() 함수를 호출할 때마다 함수 내부의 내용이 진행

📌  next() 함수를 호출한 이후 yield 키워드를 만나지 못하고 함수가 끝나면 StopIteration 이라는 예외가 발생

 

 

 

 

 

 

 

 

 

[ 내용참고 : 책 '혼자 공부하는 파이썬' ]


1. 재귀함수

1) 팩토리얼  factorial

 n ! = n * (n-1) * (n-2) * ... * 1

 

 👾  이러한 팩토리얼을 구하는 방법은 2가지로 구분

       a. 반복문 사용

       b. 재귀 함수 사용

 

A. 반복문으로 팩토리얼 구하기

def factorial(n):
    output = 1
    for i in range(1, n+1):
        output *= i
    return output

print("1!:", factorial(1))
print("2!:", factorial(2))
print("3!:", factorial(3))
print("4!:", factorial(4))
'''
1!: 1
2!: 2
3!: 6
4!: 24
'''

 

 

B. 재귀 함수로 팩토리얼 구하기

   - 재귀 recursion 란 '자기 자신을 호출하는 것'을 의미

f(4) = 4 * f(3)
     = 4 * 3 * f(2)
     = 4 * 3 * 2 * f(1) * f(0)
     = 4 * 3 * 2 * 1 * 1
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
        
print("1!:", factorial(1))
print("2!:", factorial(2))
print("3!:", factorial(3))
print("4!:", factorial(4))

 


 

2. 피보나치 수열  Fibonacci numbers

 

👩🏻‍💻  피보나치 수를 처음 연구한 것은 레오나르도 피오나치로 토끼 수의 증가에 대해서 이야기하면서 이 수에 대해 언급했다 

   

  📌  n 번째 달의 토끼 수

  • 첫 달에는 새로 태어난 토끼 한 쌍만이 존재한다.
  • 두 달 이상이 된 토끼는 번식 가능하다.
  • 번식 가능한 토끼 한 쌍은 매달 새끼 한 쌍을 낳는다.
  • 토끼는 죽지 않는다.

출처 : commons.wikimedia.org

 

 

    📌  1번째 수열 = 1

           2번째 수열 = 1

           n번째 수열 = (n-1)번째 수열 + (n-2)번째 수열

 

def fibonacci(n):
    if n == 1:
        return 1
    if n == 2:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)
        
print("fibonnaci(1):", fibonacci(1))
print("fibonnaci(2):", fibonacci(2))
print("fibonnaci(3):", fibonacci(3))
print("fibonnaci(4):", fibonacci(4))
'''
fibonnaci(1): 1
fibonnaci(2): 1
fibonnaci(3): 2
fibonnaci(4): 3
'''

 

count = 0

def fibonacci(n):
    print("fibonacci({})를 구합니다.".format(n))
    global count
    count += 1
    
    if n == 1:
        return 1
    if n == 2:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)
        
 fibonacci(10)
 print("---")
 print("fibonacci(10) 계산에 활용된 덧셈 횟수는 {}번입니다.".format(count))
 '''
fibonacci(10)를 구합니다.
fibonacci(9)를 구합니다.
...생략...
fibonacci(1)를 구합니다.
fibonacci(2)를 구합니다.
---
fibonacci(10) 계산에 활용된 덧셈 횟수는 109번입니다.
'''

 

💡  위와 같이 덧셈 횟수가 기하급수적으로 늘어나는 이유

 

 

 👾  다음과 같은 형태의 그림을 트리 tree 라고 한다.

 👾  트리에 있는 각각의 지점을 노드 node, 마지막 단계의 노드를 리프 leaf 

     ➡️  트리 내부에 있는 각각의 노드 값을 계산하려면 덧셈을 한 번씩 해야 함

      ➡️  한 번 구한 값은 그것으로 계산이 끝나는 게 아니라,

            한 번 구했던 값이라도 처음부터 다시 계산해야 함

      ➡️  이 때문에 계산 횟수가 기하급수적으로 늘어나는 것

 

 


 

💡 위의 예제에서 global count를 쓰는 이유

   

    - 파이썬은 함수 내부에서 함수 외부에 있는 변수를 참조하지 못한다.

    - 함수 내부에서 함수 외부에 있는 변수라는 것을 설명하려면 다음과 같은 구문을 사용해야 UnboundLocalError가 발생하지 않는다.

global 변수 이름

 


 

3. 메모화

👩🏻‍💻  한 번 계산한 값을 저장해 놓은 후, 이후에 다시 계산하지 않고 저장된 값을 활용하는 기술

# 메모 변수 생성
dic = {
    1: 1,
    2: 1
}

def fibonacci(n):
    if n in dic:
        # 메모가 되어 있으면 메모된 값을 리턴
        return dic[n]
    else:
        # 메모가 되어 있지 않으면 값을 구함
        output = fibonacci(n-1) + fibonacci(n-2)
        dic[n] = output
        return output
# 함수 호출        
print("fibonnaci(10):", fibonacci(10))
print("fibonnaci(20):", fibonacci(20))
print("fibonnaci(30):", fibonacci(30))
print("fibonnaci(40):", fibonacci(40))

 

 

👾  딕셔너리를 사용해서 한 번 계산한 값을 저장, 이를 메모한다고 표현

👾  딕셔너리에 값이 메모되어 있으면 처리를 수행하지 않고 곧바로 메모된 값을 돌려주면서 코드 속도를 빠르게 만든다.

 


 

4. 리스트 평탄화

👩🏻‍💻  중첩된 리스트가 있을 때 중첩을 모두 제거하고 풀어서 1차원 리스트로 만드는 것을 의미

 

def flatten(data):
    output = []
    for item in data:
        if type(item) == list:
            output += flatten(item)
        else:
            output.append(item)
    return output
    
 example = [[1,2,3], [4,[5,6]], 7, [8, 9]]
 print(flatten(example))
 # [1, 2, 3, 4, 5, 6, 7, 8, 9]

 

  ⚡️  append() 함수는 매개변수 하나를 리스트의 마지막 요소로 추가

         ➡️ append(리스트_자료형) 형태로 리스트를 전달하면 리스트 전체가 하나의 요소로서 추가됨

  ⚡️  += 연산자는 오른쪽에 있는 '리스트의 요소'를 하나하나 리스트에 추가

 

 

 

 

 

[ 내용 참고 : 책 '혼자 공부하는 파이썬']

+ Recent posts