본문 바로가기
개발일지/Python

22.03.03 [파이썬 웹개발] 함수고급(레이터시리즈)

by 개발에정착하고싶다 2022. 3. 3.
320x100

파이썬 웹개발 코스의 시작에 있어서는

멀티캠퍼스의 과정처럼 장고로 웹개발을 잘 실천하기 위해서 구매했지만

중간에 어떤 책을 읽고 마음을 바꾸었다.

 

계기는 그 사람이 "html같은걸 왜 배우는지 이해가 안된다. 어차피 쓰지도 않는데"라고 했다.

그리고 이걸 실제로 쓰는 사람도 있겠지만

모르는 내가 본능적으로 느꼈을때 이것말고도 더 중요한게 많은데 굳이 여기에 메일 필요는 없다고 생각이 들었다.

때문에 파이썬 강의만 들은 것으로 일단은 만족하려고 한다.

 

더불어서 파이썬 강의의 대부분은 이제 "이해"가 가능한 수준이 되었다.

하지만 그 이해가 유기적인 이해는 아닌지라, 아주 작은 프로젝트를 하려고해도

"이걸 어떻게해?"라는 생각이 드는 느낌이다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

진짜 ㅄ같네 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

배웠고 이해했는데 그걸 못한다니

 

암튼 재밌네 여러가지 의미로

 

그리고 언제가 될진 모르겠지만 "그 때"가 올때까지는 그냥 무작정 무지성으로 따라하기만 하려고 한다.

언젠간 나도 차근차근 구현 할 수 있을 정도로 쌓일때가 오겠지 뭐.

 

암튼 마지막 파이썬 정리 들어간다.

 

 

chapter 1 일급객체

 

# 일급객체란?
# - 다음과 같은 특징을 만족하는 객체를 말한다.
# 1. 데이터 처럼 사용이 가능하다.
# 2. 매개변수에 넘겨 줄 수 있다.
# 3. 리턴 값으로 사용될 수 있다.

# 1. 데이터 처럼 사용이 가능하다.


# 1) 함수를 변수에 할당 가능
def func(x, y):
    return x+y

add = func(4,3)
print(add)

# 2) 리스트(튜플, 딕셔너리 등)에 할당 가능
def mul(x,y):
    return x*y

def div(x,y):
    return x/y

calculator = [mul, div]
print(calculator[0](5,6))

# 2. 매개변수에 넘겨 줄 수 있다.
def inputData():
    data = input("데이터 입력>>>")
    return data


def start(func):
    print("입력한 데이터는", func())

start(inputData)



# 3. 리턴 값으로 사용될 수 있다.
def plusTen(a):

    return a+10

def func(x):
    return plusTen(x)

print(func(5))
 
 
==============================================================

chapter2  클로저

 

# 1. 내부함수
# 함수 안에 또 다른 함수를 정의할 수 있다.

def outer(name):
    def inner():
        print(name, "님 안녕하세요")
    return inner

func = outer("startcoding")
# func()


# 2. 클로저
# 함수가 종료되어도 자원을 사용할 수 있는 함수

# ** 클로저가 될 조건
# 1) 내부 함수 여야 한다.
# 2) 외부 함수의 변수를 참조해야 한다.
# 3) 외부 함수가 내부 함수를 반환해야 한다.

def greeting(name, age, gender):
    def inner():
        print(name, "님 안녕하세요!")
        print("나이:",age)
        print("성별:",gender)
    return inner

closure = greeting("나미",27,"famale")
closure()

# print(closure.__closure__[0].cell_contents)

for i in closure.__closure__:
    print(i.cell_contents)


# 전역변수를 사용해서 대체가 가능하다.
# 하지만 전역변수는 사용을 최소화 하는 것이 좋다 (네이밍 문제, 스코프 문제)

================================================================

chapter3  이터레이터(1)

 

# 이터레이터

# 1. 이터러블 객체 (iterable object)
# 문자열, 리스트, 튜플, 딕셔너리, range 객체

# for i in "123":
#     print(i)


# for i in [10,20,30]:
#     print(i)

iter_obj = print([10,20,30].__iter__())

# print(iter_obj)

iter_obj = [10,20,30].__iter__()
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__()) # 리스트에 들어있는 것이 10,20,30 이기때문에 이를 넘기게 되니 StopIteration 를 출력해주게된다.

==============================================================

chapter4  이터레이터(2)

 

# 이터레이터 생성 방법

# 클래스정의 해주고
# __iter__
# __next__ 를 해주면 된다.

class Seasons:
    def __init__(self):
        self.season_list = ["spring","summer","autumn","winter"]
        self.idx = 0
        self.max_num = 4
       
    def __iter__(self):
        return self

    def __next__(self):
        if self.idx < self.max_num:
            curr_idx = self.idx
            self.idx +=1

            return self.season_list[curr_idx]
        else:
            raise StopIteration


# for i in Seasons():
#     print(i)


iter_obj = Seasons().__iter__()

print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())
print(iter_obj.__next__())

==============================================================

chapter5  제너레이터(1)

 

# 제너레이터

# 1.이터레이터를 만드는 함수

def season_generator(*args):
    for arg in args:
        yield arg

g = season_generator("spring","summer","autumn","winter")

print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
# print(g.__next__()) # StopIteration


# return 도 yield도 결과값 도출이다.
# 그러나 이렇게 1,2,3로 연계되어있는 연결성 결과값에 대해서는 yield로 쓰인다.
def func():
    print("첫번째 작업 중...")
    yield 1

    print("두번째 작업 중...")
    yield 2

    print("세번째 작업 중...")
    yield 3


ge = func()
data = ge.__next__()
print(data)
data = ge.__next__()
print(data)
data = ge.__next__()
print(data)
data = ge.__next__() # StopIteration
print(data)

==============================================================

chapter6  제너레이터(2)

 

# 2. 제너레이터 표현식
double_generator = (i*2 for i in range(1,10))


for i in double_generator:
    print(i)


# 3. 메모리 사용을 효율적으로 하기 위하여 사용
# ex) 숫자 1-10000 3배로 만든 결과 리스트 vs 제너레이터

import sys # 최소한 여기서의 기능은, 리스트, 제너레이터 둘다 메모리를 얼마나 잡아먹고 있는지 확인하고자 쓰였다.

list_data = [i*3 for i in range(1,10000 + 1)]
generator_data = (i*3 for i in range(1,10000 + 1)) # 리스트를 대괄호 []로 씌웠다면, 소괄호인 ()로 씌운것이 제너레이터다.


# 리스트: 데이터 저장에 필요한 메모리를 모두 사용
# 제너레이터: 나중에 필요할 때 값을 만들어서 사용(메모리 적게 필요)
print(sys.getsizeof(list_data)) # 87616 bytes
print(sys.getsizeof(generator_data)) # 112 bytes

'''
리스트와 제너레이터가 이렇게 메모리 차이가 나는 이유는
리스트의 경우는 i를 range안에서 돌릴때 마다 list_data 안에 리스트화 해서 파일을 저장한다.

반면, 제너레이터는 __next__ 의 원리로 값은 range안의 것을 리스트와 동일하게 출력하지만, 그것을 저장해놓지 않는다.
'''

==============================================================

chapter7  데코레이터

 

# 데코레이터
# 함수의 앞, 뒤로 부가적인 기능을 넣어주고 싶을 때 사용
# 로깅, 권한


# 데코레이터 생성하기


def logger(func):
    def wrapper(arg):
        print("함수 시작")
        func(arg) # 함수 실행
        print("함수 끝")
    return wrapper

@logger
def print_hello(name):
    print("hello startcoding",name)
   

@logger
def print_bye(name):
    print("bye fastcampus",name)
   

print_hello("startcoding")
print_bye("fastcampus")

==============================================================

 

300x250