찾다
백엔드 개발파이썬 튜토리얼한 기사로 Python 데코레이터 이해하기

한 기사로 Python 데코레이터 이해하기

Python은 초보자에게 친숙한 언어입니다. 그러나 데코레이터와 같이 마스터하기 어려운 고급 기능도 많이 있습니다. 많은 초보자들은 데코레이터와 그 작동 방식을 전혀 이해하지 못했습니다. 이 기사에서는 데코레이터의 모든 것을 소개합니다.

Python에서 함수는 매우 유연한 구조입니다. 변수에 할당하거나, 다른 함수에 매개변수로 전달하거나, 함수의 출력으로 사용할 수 있습니다. 데코레이터는 본질적으로 다른 함수가 수정 없이 일부 기능을 추가할 수 있도록 하는 함수입니다.

이것은 "장식"의 의미입니다. 이 "장식" 자체가 기능을 나타냅니다. 다른 기능을 수정하는 데 사용한다는 것은 해당 기능에 이 기능을 추가하는 것을 의미합니다.

일반적으로 데코레이터에서 제공하는 @ 구문 설탕(Syntactic Sugar)을 사용하여 다른 기능이나 객체를 장식할 수 있습니다. 아래와 같이 @dec 데코레이터를 사용하여 func() 함수를 장식합니다.

@dec
def func():
 pass

데코레이터를 이해하는 가장 좋은 방법은 데코레이터가 해결하는 문제가 무엇인지 이해하는 것입니다. 문제를 해결하고 우아함과 강력함을 보여줍니다.

설정 문제

데코레이터의 목적을 이해하기 위해 간단한 예를 살펴보겠습니다. 두 번째 매개변수의 기본값이 10인 간단한 덧셈 함수 dec.py가 있다고 가정해 보겠습니다.

# dec.py
def add(x, y=10):
 return x + y

이 덧셈 함수를 자세히 살펴보겠습니다.

>>> add(10, 20)
30
>>> add
<function add at 0x7fce0da2fe18>
>>> add.__name__
'add'
>>> add.__module__
'__main__'
>>> add.__defaults__ # default value of the `add` function
(10,)
>>> add.__code__.co_varnames # the variable names of the `add` function
('x', 'y')

이것이 무엇인지 이해할 필요는 없습니다. Python의 모든 함수는 객체이며 다양한 속성과 메서드를 가지고 있습니다. 검사 모듈을 통해 add() 함수의 소스 코드를 볼 수도 있습니다:

>>> from inspect import getsource
>>> print(getsource(add))
def add(x, y=10):
 return x + y

이제 어떤 방식으로든 더하기 함수를 사용합니다. 예를 들어 몇 가지 작업을 사용하여 함수를 테스트합니다.

# dec.py
from time import time
def add(x, y=10):
 return x + y
print('add(10)', add(10))
print('add(20, 30)', add(20, 30))
print('add("a", "b")', add("a", "b"))
Output: i
add(10) 20
add(20, 30) 50
add("a", "b") ab

원하는 경우 각 작업의 기능 이해 시간에 대해 시간 모듈을 호출할 수 있습니다:

# dec.py
from time import time
def add(x, y=10):
 return x + y
before = time()
print('add(10)', add(10))
after = time()
print('time taken: ', after - before)
before = time()
print('add(20, 30)', add(20, 30))
after = time()
print('time taken: ', after - before)
before = time()
print('add("a", "b")', add("a", "b"))
after = time()
print('time taken: ', after - before)
Output:
add(10) 20
time taken:6.699562072753906e-05
add(20, 30) 50
time taken:6.9141387939453125e-06
add("a", "b") ab
time taken:6.9141387939453125e-06

이제 프로그래머로서 조금 가려우신가요? 결국 우리는 항상 동일한 코드를 복사하여 붙여넣는 것을 좋아하지 않습니다. 현재 코드는 읽기가 쉽지 않습니다. 무언가를 변경하려면 해당 코드가 나타나는 모든 부분을 수정해야 합니다. Python에는 더 나은 방법이 있을 것입니다.

다음과 같이 추가 기능에서 실행 시간을 직접 캡처할 수 있습니다.

# dec.py
from time import time
def add(x, y=10):
 before = time()
 rv = x + y
 after = time()
 print('time taken: ', after - before)
 return rv
print('add(10)', add(10))
print('add(20, 30)', add(20, 30))
print('add("a", "b")', add("a", "b"))

이 방법은 이전 방법보다 확실히 좋습니다. 하지만 다른 기능이 있으면 불편할 것 같습니다. 여러 함수가 있는 경우:

# dec.py
from time import time
def add(x, y=10):
 before = time()
 rv = x + y
 after = time()
 print('time taken: ', after - before)
 return rv
def sub(x, y=10):
 return x - y
print('add(10)', add(10))
print('add(20, 30)', add(20, 30))
print('add("a", "b")', add("a", "b"))
print('sub(10)', sub(10))
print('sub(20, 30)', sub(20, 30))

add와 sub가 모두 함수이기 때문에 이를 활용하여 타이머 함수를 작성할 수 있습니다. 우리는 타이머가 함수의 작동 시간을 계산하기를 원합니다:

def timer(func, x, y=10):
 before = time()
 rv = func(x, y)
 after = time()
 print('time taken: ', after - before)
 return rv

이것은 좋지만 다음과 같이 다른 함수를 타이머 함수로 래핑해야 합니다.

print('add(10)', timer(add,10)))

이제 기본값은 여전히 ​​10인가요? 반드시 그런 것은 아닙니다. 그렇다면 어떻게 하면 더 잘할 수 있을까요?

아이디어는 다음과 같습니다. 새 타이머 함수를 만들고, 다른 함수를 래핑하고, 래핑된 함수를 반환합니다.

def timer(func):
 def f(x, y=10):
 before = time()
 rv = func(x, y)
 after = time()
 print('time taken: ', after - before)
 return rv
 return f

이제 add 및 sub 함수를 타이머로 래핑하기만 하면 됩니다.

add = timer(add)

그렇습니다! 전체 코드는 다음과 같습니다.

# dec.py
from time import time
def timer(func):
 def f(x, y=10):
 before = time()
 rv = func(x, y)
 after = time()
 print('time taken: ', after - before)
 return rv
 return f
def add(x, y=10):
 return x + y
add = timer(add)
def sub(x, y=10):
 return x - y
sub = timer(sub)
print('add(10)', add(10))
print('add(20, 30)', add(20, 30))
print('add("a", "b")', add("a", "b"))
print('sub(10)', sub(10))
print('sub(20, 30)', sub(20, 30))
Output:
time taken:0.0
add(10) 20
time taken:9.5367431640625e-07
add(20, 30) 50
time taken:0.0
add("a", "b") ab
time taken:9.5367431640625e-07
sub(10) 0
time taken:9.5367431640625e-07
sub(20, 30) -10

프로세스를 요약해 보겠습니다. 추가 기능과 같은 기능이 있고 타이밍과 같은 작업으로 해당 기능을 래핑합니다. 패키징의 결과는 특정한 새로운 기능을 구현할 수 있는 새로운 기능입니다.

물론 기본값에 문제가 있으니 나중에 수정하겠습니다.

Decorator

이제 위의 솔루션은 일반적인 동작을 사용하여 특정 기능을 래핑하는 데코레이터의 아이디어에 매우 가깝습니다. 데코레이터를 사용한 후의 코드는 다음과 같습니다.

def add(x, y=10):
 return x + y
add = timer(add)
You write:
@timer
def add(x, y=10):
 return x + y

둘 다 동일한 효과를 가지며, 이것이 Python 데코레이터가 수행하는 작업입니다. 구현하는 함수는 데코레이터가 함수 위에 구문을 배치하고 구문이 @timer로 더 간단하다는 점을 제외하면 add = 타이머(add)와 유사합니다.

# dec.py
from time import time
def timer(func):
 def f(x, y=10):
 before = time()
 rv = func(x, y)
 after = time()
 print('time taken: ', after - before)
 return rv
 return f
@timer
def add(x, y=10):
 return x + y
@timer
def sub(x, y=10):
 return x - y
print('add(10)', add(10))
print('add(20, 30)', add(20, 30))
print('add("a", "b")', add("a", "b"))
print('sub(10)', sub(10))
print('sub(20, 30)', sub(20, 30))

매개변수 및 키워드 매개변수

아직 해결되지 않은 작은 문제가 있습니다. 타이머 함수에서는 매개변수 x와 y를 하드코딩합니다. 즉, y의 기본값을 10으로 지정합니다. 인수와 키워드 인수를 함수에 전달하는 방법, 즉 *args 및 **kwargs가 있습니다. 매개변수는 함수의 표준 매개변수(이 경우 x가 매개변수)이고 키워드 매개변수는 이미 기본값(이 경우 y=10)이 있는 매개변수입니다. 코드는 다음과 같습니다.

# dec.py
from time import time
def timer(func):
 def f(*args, **kwargs):
 before = time()
 rv = func(*args, **kwargs)
 after = time()
 print('time taken: ', after - before)
 return rv
 return f
@timer
def add(x, y=10):
 return x + y
@timer
def sub(x, y=10):
 return x - y
print('add(10)', add(10))
print('add(20, 30)', add(20, 30))
print('add("a", "b")', add("a", "b"))
print('sub(10)', sub(10))
print('sub(20, 30)', sub(20, 30))

이제 타이머 함수는 이러한 매개변수를 함수에 전달하기 때문에 모든 함수, 매개변수 및 기본값 설정을 처리할 수 있습니다.

Higher Order Decorators

궁금하실 수도 있습니다. 유용한 동작을 추가하기 위해 함수를 다른 함수로 래핑할 수 있다면 한 단계 더 나아갈 수 있을까요? 함수를 다른 함수로 래핑하고 다른 함수로 래핑합니까?

예! 실제로 기능은 원하는 만큼 깊어질 수 있습니다. 예를 들어, 함수를 n번 실행하는 데코레이터를 작성하려고 합니다. 아래와 같이:

def ntimes(n):
 def inner(f):
 def wrapper(*args, **kwargs):
 for _ in range(n):
 rv = f(*args, **kwargs)
 return rv
 return wrapper
 return inner

그런 다음 위 함수를 사용하여 이전 기사의 add 함수와 같은 다른 함수를 래핑할 수 있습니다.

@ntimes(3)
def add(x, y):
 print(x + y)
 return x + y

출력 문은 코드가 실제로 3번 실행되었음을 보여줍니다.

위 내용은 한 기사로 Python 데코레이터 이해하기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 51CTO.COM에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
Python vs. C : 응용 및 사용 사례가 비교되었습니다Python vs. C : 응용 및 사용 사례가 비교되었습니다Apr 12, 2025 am 12:01 AM

Python은 데이터 과학, 웹 개발 및 자동화 작업에 적합한 반면 C는 시스템 프로그래밍, 게임 개발 및 임베디드 시스템에 적합합니다. Python은 단순성과 강력한 생태계로 유명하며 C는 고성능 및 기본 제어 기능으로 유명합니다.

2 시간의 파이썬 계획 : 현실적인 접근2 시간의 파이썬 계획 : 현실적인 접근Apr 11, 2025 am 12:04 AM

2 시간 이내에 Python의 기본 프로그래밍 개념과 기술을 배울 수 있습니다. 1. 변수 및 데이터 유형을 배우기, 2. 마스터 제어 흐름 (조건부 명세서 및 루프), 3. 기능의 정의 및 사용을 이해하십시오. 4. 간단한 예제 및 코드 스 니펫을 통해 Python 프로그래밍을 신속하게 시작하십시오.

파이썬 : 기본 응용 프로그램 탐색파이썬 : 기본 응용 프로그램 탐색Apr 10, 2025 am 09:41 AM

Python은 웹 개발, 데이터 과학, 기계 학습, 자동화 및 스크립팅 분야에서 널리 사용됩니다. 1) 웹 개발에서 Django 및 Flask 프레임 워크는 개발 프로세스를 단순화합니다. 2) 데이터 과학 및 기계 학습 분야에서 Numpy, Pandas, Scikit-Learn 및 Tensorflow 라이브러리는 강력한 지원을 제공합니다. 3) 자동화 및 스크립팅 측면에서 Python은 자동화 된 테스트 및 시스템 관리와 ​​같은 작업에 적합합니다.

2 시간 안에 얼마나 많은 파이썬을 배울 수 있습니까?2 시간 안에 얼마나 많은 파이썬을 배울 수 있습니까?Apr 09, 2025 pm 04:33 PM

2 시간 이내에 파이썬의 기본 사항을 배울 수 있습니다. 1. 변수 및 데이터 유형을 배우십시오. 이를 통해 간단한 파이썬 프로그램 작성을 시작하는 데 도움이됩니다.

10 시간 이내에 프로젝트 및 문제 중심 방법에서 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법?10 시간 이내에 프로젝트 및 문제 중심 방법에서 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법?Apr 02, 2025 am 07:18 AM

10 시간 이내에 컴퓨터 초보자 프로그래밍 기본 사항을 가르치는 방법은 무엇입니까? 컴퓨터 초보자에게 프로그래밍 지식을 가르치는 데 10 시간 밖에 걸리지 않는다면 무엇을 가르치기로 선택 하시겠습니까?

중간 독서를 위해 Fiddler를 사용할 때 브라우저에서 감지되는 것을 피하는 방법은 무엇입니까?중간 독서를 위해 Fiddler를 사용할 때 브라우저에서 감지되는 것을 피하는 방법은 무엇입니까?Apr 02, 2025 am 07:15 AM

Fiddlerevery Where를 사용할 때 Man-in-the-Middle Reading에 Fiddlereverywhere를 사용할 때 감지되는 방법 ...

Python 3.6에 피클 파일을로드 할 때 '__builtin__'모듈을 찾을 수없는 경우 어떻게해야합니까?Python 3.6에 피클 파일을로드 할 때 '__builtin__'모듈을 찾을 수없는 경우 어떻게해야합니까?Apr 02, 2025 am 07:12 AM

Python 3.6에 피클 파일로드 3.6 환경 보고서 오류 : modulenotfounderror : nomodulename ...

경치 좋은 스팟 코멘트 분석에서 Jieba Word 세분화의 정확성을 향상시키는 방법은 무엇입니까?경치 좋은 스팟 코멘트 분석에서 Jieba Word 세분화의 정확성을 향상시키는 방법은 무엇입니까?Apr 02, 2025 am 07:09 AM

경치 좋은 스팟 댓글 분석에서 Jieba Word 세분화 문제를 해결하는 방법은 무엇입니까? 경치가 좋은 스팟 댓글 및 분석을 수행 할 때 종종 Jieba Word 세분화 도구를 사용하여 텍스트를 처리합니다 ...

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

DVWA

DVWA

DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경