반응형
  • 함수의 앞 뒤 부가적인 기능을 넣어주고 싶을때 사용한다
  • 클로저를 사용해서 구현한다.
def logger(func):
  def wrapper():
    print("함수시작")
    func()
    print("함수종료")
  return wrapper

@logger
def print_hi():
  print("hi")

print_hi()


# OUTPUT
함수시작
hi
함수종료

 

728x90
반응형
반응형
  • 이터러블 객체
    • 순서가 있는 자료형
    • 문자열, 리스트, 튜플, 딕셔너리, range 객체
    • __iter__(), __next__() 메소드가 정의되어있다.
  • 제너레이터 함수
    • 이터레이터를 만드는 함수이다.
    • yield 사용한다
    • 제너레이터 표현식을 사용해서 만들 수 있다.
    • 메모리 사용이 효율적이다.
      • List 같은 경우 결과 값을 메모리에 저장한다.
      • 제너레이터의 경우 식만 저장할뿐 값을 저장 하지 않는다. __next__ 함수가 호출 될 때에 결과값을 만든다
# yield 사용
def gen_func(*args):
  for arg in args:
    yield arg

month = gen_func('1월', '2월', '3월', '4월')

print(month.__next__())   # 1월
print(month.__next__())   # 2월
print(month.__next__())   # 3월
print(month.__next__())   # 4월


# 제너레이터 표현식 -> () 를 사용한다.
double_generator = (i * 2 for i in range(1,10))

for i in double_generator:
  print(i)


# 메모리 차이
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))       # 85176
print(sys.getsizeof(generator_data))  # 208

 

728x90
반응형
반응형
  • 내부함수
    • 함수 안에서 정의 되는 함수
  • 클로저(closure)
    • 함수가 종료되어도 자원을 사용할 수 있는 함수
    • 클로저 조건
      • 내부함수
      • 외부함수 변수를 참조해야 한다.
      • 외부함수가 내부함수를 반환 해야 한다.
def outer(name):			# 외부함수
  def inner():				# 내부함수
    print(name, "하이")			# 외부함수 변수 참조
  return inner				# 내부함수 반환
  
callfunc = outer("tom")  
callfunc()  

# OUTPUT
tom 하이
  • 클로저 살펴보기
print(dir(callfunc))
# ['__annotations__', '__builtins__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__getstate__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
print(type(callfunc.__closure__))
# <class 'tuple'>
print(callfunc.__closure__[0])
# <cell at 0x00000233CBE8A6E0: str object at 0x00000233CBE93B30>
print(dir(callfunc.__closure__[0]))
# ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
print(callfunc.__closure__[0].cell_contents)
# tom
  • 라인 1: dir 로 callfunc 를 살표보면 __closure__ 가 존재하는것을 볼수 있다.
  • 라인 3: __closure__ 의 타입은 tuple 이다.
  • 라인 5: __closure__[0] 번째 항목을 출력한 결과이다.
  • 라인 7:__closure__[0] 을 dir 로 살펴보면 cell_contents 가 존재하는 것을 볼수 있다.
  • 라인 9: cell_contents 를 출력해보면 외부함수 변수의 값인 tom 이 있는것을 확인 할 수 있다.
  • 위 코드에서 callfunc = outer("tom") 호출 시점에 외부함수는 종료가 된다. 하지만 종료가 된 후에도 callfunc() 가 외부함수 변수 값인 "tom" 을 출력할 수 있는 이유는 클로저 공간에 변수의 값을 저장하고 있기 때문이다.

 

728x90
반응형
반응형
  • 인스턴스 메소드
    • 인스턴스 속성에 접근하는 메소드
    • self 를 파라미터로 받는다.
  • 클래스 메소드
    • 클래스 속성에 접근하는 메소드
    • 클래스를 의미하는 cls 를 파라미터로 받는다
    • @classmethod 를 붙인다
class Unit:
  count = 0
  def __init__(self, name, weight, height, hidden):
    self.name=name
    self.weight=weight
    self.height=height
    self.__hidden=hidden
    Unit.count +=1
    print(f"{self.name} Unit 생성")
  
  def __str__(self):
    return f"name={self.name} weight={self.weight} height={self.height}"
  
  # 인스턴스 메소드
  # 인스턴스 속성에 접근하는 메소드
  def loseWeight(self, value):
    self.weight = self.weight - value
    print(f"무게가 {value} 만큼 줄었습니다. 현재는 {self.weight} 입니다.")

  # 클래스 메서드
  # 클래스 속성에 접근하는 메소드
  # cls를 파라미터로 받는다
  @classmethod
  def print_count(cls):
    print(f"생성된 Unit 개수 = {cls.count}")
    
unit1 = Unit("Unit1", 20, 30, "magic")
print(unit1)
print(unit1.loseWeight(10))
Unit.print_count()

# OUTPUT
Unit1 Unit 생성
name=Unit1 weight=20 height=30
무게가 10 만큼 줄었습니다. 현재는 10 입니다.
생성된 Unit 개수 = 2
  • 정적 메소드
    • 인스턴스를 만들 필요가 없다.
    • self 를 받지 않는다.
    • @staticmethod 를 붙인다
class Math:
  @staticmethod
  def add(x,y):
    return x+y

print(Math.add(3,5))
  • 매직 메소드
    • __이름__ 형태로 되어있다.
    • __init__ : 객체가 생성될때 실행되는 메소드
    • __str__ :  객체를 출력하는 메소드

 

728x90
반응형
반응형
  • 인스턴스 속성
    • 객체마다 다르게 갖고 있는 속성
    • 코드에서 self 로 표기된 속성들이 인스턴스 속성이다.
  • 클래스 속성
    • 모든 객체가 공유하는 속성
    • count 가 클래스 속성
    • 접근시에는 클래스이름.속성 으로 접근 (ex : Unit.count)
  • 비공개 속성
    • 클래스 안에서만 접근 가능한 속성
    • __hidden 이 비공개 속성이다.
    • 외부에서 변경시 Unit.__hidden 으로는 접근이 불가능 하다
    • 네이밍 맹글링에 의해서 접근은 가능하다 (unit1._Unit__hidden)
class Unit:
  count = 0
  def __init__(self, name, weight, height, hidden):
    self.name=name
    self.weight=weight
    self.height=height
    self.__hidden=hidden
    Unit.count +=1
    print(f"{self.name} Unit 생성")
  
  def __str__(self):
    return f"name={self.name} weight={self.weight} height={self.height}"


unit1 = Unit("Unit1", 20, 30, "magic")
unit2 = Unit("Unit2", 100, 200, "power")

print(unit1)
print(unit2)
print(Unit.count)
print(unit1._Unit__hidden)

# OUTPUT
Unit1 Unit 생성
Unit2 Unit 생성
name=Unit1 weight=20 height=30
name=Unit2 weight=100 height=200
2
magic

 

728x90
반응형
반응형
  • map 함수
    • map(함수, 순서가 있는 자료형)
    • map 의 결과는 map object 이기 때문에 사용하기 편한 list 형태로 변환한다.
def remove_blank(x):
  return x.strip()

items=[' mouse', ' monitor ']

items=list(map(remove_blank, items))

print(items)

# output
# ['mouse', 'monitor']

# 람다함수로 표기할 경우
items=list(map(lambda x:x.strip(), items))

 

  • filter 함수
    • filter(함수, 순서가 있는 자료형)
def func(x):
  return x < 0

print(list(filter(func, [-3, 0, 2, 7, -7])))

# output
# [-3, -7]

# 람다함수로 표현
print(list(filter(lambda x:x<0, [-3, 0, 2, 7, -7])))

 

728x90
반응형
반응형
  • 람다함수를 사용하면 코드가 간결해진다
  • 메모리 사용이 효율적이다.
# 람다함수 선언 방법
lambda a : a-1

# 호출방법 1 : 그대로 호출
print ((lambda a:a-1)(10))

# 호출방법 2 : 변수에 담아서 호출
minus_ten = lambda a : a-10
print (minus_ten(100))

# 람다함수 if 문 사용
def is_positive_num(a):
  if a > 0:
    return True
  else:
    return False

lambda a : True if a > 0 else False

개인적으로 함수 자체를 호출하는 방법보다는 변수에 담아서 호출하는게 가독성에는 더 좋아보인다.

 

728x90
반응형

'Development > Python' 카테고리의 다른 글

[파이썬 문법] python class 속성들  (0) 2023.03.02
[파이썬 문법] map, filter 함수  (0) 2023.02.28
[파이썬 문법] 키워드 가변 매개변수  (0) 2023.02.27
[파이썬 문법] 튜플  (0) 2023.02.27
Python 가상환경  (0) 2022.10.27
반응형
  • 매개변수 앞에 ** 가 붙는다
  • 딕셔너리 로 인식한다.
def comment_info(**kwargs):
  print(kwargs)
  for key,value in kwargs.items():
    print(f'{key}:{value}')

comment_info(name='test1', age=10)

output
{'name': 'test1', 'age': 10}
name:test1
age:10

 

728x90
반응형

'Development > Python' 카테고리의 다른 글

[파이썬 문법] map, filter 함수  (0) 2023.02.28
[파이썬 문법] 파이썬 람다 함수  (0) 2023.02.27
[파이썬 문법] 튜플  (0) 2023.02.27
Python 가상환경  (0) 2022.10.27
Ubuntu 에서 파이썬 버전 확인 및 변경  (0) 2022.10.25
반응형
  • 튜플은 () 로 정의된다
  • 튜플은 값을 바꿀수 없다.
t1 = ()
t2 = (1,)
t3 = (1,2,3)
t4 = 1,2,3
t5 = ('a', 'b', ('ab', 'cd'))
  • 1개의 요소만 가질때에는 콤마(,) 를 붙여야 한다.
  • 괄호가 생략 가능하다
  • 개수가 정해지지 않은 매개 변수로 사용된다. (* 가 매개변수 앞에 붙는다.) = 위치가변 매개변수
def print_fruits(*args):
  print(args)
  for arg in args:
    print(arg)

print_fruits('apple', 'banana', 'melon')

output
('apple', 'banana', 'melon')
apple
banana
melon

 

728x90
반응형

+ Recent posts