Table of Contents

728x90

클래스Class

# 파일명 Multiply.py
class Mul: #클래스 Mul생성
    def __init__(self, m): # __init__은 Mul클래스의 생성자 특수 함수 Mul 클래스의 인스턴스(객체)가 생성될 때 자동으로 호출
        self.m = m  # self: 인스턴스 자기 자신을 참조하는 변수
                    # self.m: 인스턴스에 m이라는 속성을 만들고, 이 속성은 인스턴스가 존재하는 동안 계속 접근할 수 있습니다. 
                    # m: 생성자로 전달된 인자, x,y,z등 아무 이름을 넣어줘도 됨
                    # return값이 없다
                    
    def mul(self, n): # 클래스 내의 메서드(함수)
        return self.m*n # 이 메서드를 실행하면 반환될 결과값은 m*n이다

if __name__ == '__main__': # python파일(Multiply.py)을 호출할 때 자동으로 실행되는 부분
    mul3 = Mul(3) # 무조건 인스턴스를 생성부터 해줘야 함
    mul5 = Mul(5) # Mul(3)은 Mul클래스를 m값을 3으로 하여 생성한다는 뜻, 이러한 생성을 mul3이라고 정함
    
    # 인스턴스를 생성했으면 인스턴스를 호출한다
    print(mul3.mul(10)) # 앞서서 mul3 은 Mul(3)이었고 m은 3. Mul클래스를 통해 mul 함수에 접근하여 n=10을 할당하여 m*n을 실행 결과값은 3*10=30
    print(mul5.mul(10)) # 결과값은 5*10 = 50

 

이렇게 def mul 함수를 __call__ 함수로 바꿔줘도 된다.

class Mul: #클래스 Mul생성
    def __init__(self, m):  
        self.m = m 
                                       
    def __call__(self, n): #클래스의 인스턴스를 함수처럼 호출할 수 있게 해주는 특수 메소드. 이 메소드를 정의하면 객체를 마치 함수처럼 사용할 수 있으며, 객체를 호출할 때 실행.
        return self.m * n  #return 값이 있음
    
if __name__ == '__main__':
    mul3 = Mul(3)  # 인스턴스 생성
    mul5 = Mul(5)
    
    print(mul3(10)) # 인스턴스 호출, 이제 def mul은 없어졌으니 mul3자체, __call__인 Mul(3)을 불러서 n=10 을 호출하면 됨, m=3 n=10 결과값은 30
    print(mul5(10)) # 결과값은 5*10 = 50

 

클로저Closure

함수 안의 함수를 결과로 반환할 때 그 내부함수를 클로저(closure)라고 한다

  • 콜백함수
  • 함수의 순차적 실행
  • 데코레이터 함수에 사용된다
def mul(m): # 외부함수
    def wrapper(n): # 내부함수(클로저) 
        return m * n
    return wrapper
    
if __name__ == '__main__':
    mul3 = mul(3) # m이 3인 wrapper함수가 mul3에 저장됨
    mul5 = mul(5) # m이 5인 wrapper함수가 mul5에 저장됨
    
    print(mul3(10)) # m=3, n=10인 wrapper함수가 실행됨
    print(mul5(10)) # m=5, n=10인 wrapper함수가 실행됨

 

데코레이터Decorator

 

함수를 꾸며주는 함수

함수를 인수로 받는 클로

@을 이용한 이노테이션으로 사용

  • 반복되는 작업을 여러 함수에 적용할 경우
  • 기존 함수를 수정하지 않고 추가 기능을 구현하고 싶을 경우
# 일반 클래스
import time

def func1(a,b): #a + b 함수 실행시간을 측정
    start = time.time()
    print("함수가 실행됩니다.")
    
    val = a + b
    end = time.time()
    print("함수 수행시간: %f 초" % (end-start))
    
    return val

if __name__ == '__main__':
    result = func1(1,2)
    print(result)
    
    
    
def func2(a,b): # a * b 함수 실행시간을 측정
    start = time.time()
    print("함수가 실행됩니다.")
    
    val = a * b
    end = time.time()
    print("함수 수행시간: %f 초" % (end-start))
    
    return val
    
if __name__ == '__main__':
    result = func2(1,2)
    print(result)

 

이렇게 a+b, a*b만 다른 경우에 다음과 같이 클로저를 사용할 수 있다.

# 클로저를 활용하여 func만 분리
import time

def func1(a,b):
    val = a + b
    return val

def func2(a,b):
    val = a * b
    return val

def elapsed(func):
    def wrapper(a,b):
        start = time.time()
        print("함수가 실행됩니다.")
        result = func(a,b)
        end = time.time()
        print("함수 수행시간: %f 초" % (end-start))
        return result
    return wrapper

if __name__ == '__main__':
    deco1 = elapsed(func1)
    result = deco1(1,2)
    print(result)
    
if __name__ == '__main__':
    deco2 = elapsed(func2)
    result = deco2(1,2)
    print(result)

 

이렇게 하면 elapsed(func1) eplapsed(func2) 두 번 호출해야 하는데 @데코레이터로 간편하게 코드를 줄일 수 있다

 

import time

def elapsed(func):
    def wrapper(a,b):
        start = time.time()
        print("함수가 실행됩니다.")
        result = func(a,b)
        end = time.time()
        print("함수 수행시간: %f 초" % (end-start))
        return result
    return wrapper

@elapsed
def func1(a,b):
    val = a + b
    return val
@elapsed
def func2(a,b):
    val = a * b
    return val

if __name__ == '__main__':
    result = func1(1,2)
    print(result)
    
if __name__ == '__main__':
    result = func2(1,2)
    print(result)

'Python' 카테고리의 다른 글

Type Annotation Convention을 따르자  (0) 2024.04.21
이터레이터iterator / 데코레이터decorator / iter, yield, next  (1) 2024.04.21
Numpy Array를 쌓기  (0) 2024.04.20
Numpy Array 쪼개기  (0) 2024.04.20
Numpy 크기차원변경  (1) 2024.04.20