Python 프로그래밍 언어의 가장 큰 장점 중 하나는 모든 기능을 매우 유용한 작은 패키지에 담았다는 것입니다.
많은 기능이 Python 코드의 기능을 완전히 변경하여 언어를 더욱 유연하게 만들 수 있습니다. 올바르게 사용하면 이러한 기능 중 일부는 프로그램 작성에 필요한 시간을 효과적으로 줄일 수 있습니다.
이러한 목표를 달성한 좋은 예는 Python의 데코레이터입니다.
데코레이터는 Python 함수 개체의 동작을 변경하는 데 사용할 수 있는 함수입니다. 클래스와 함수에 적용할 수 있고 정말 흥미로운 일을 많이 할 수 있습니다!
데코레이터를 사용하면 코드를 단축하고 속도를 높이며 Python에서 코드가 작동하는 방식을 완전히 바꿀 수 있습니다.
말할 필요도 없이 이것은 확실히 유용합니다! 오늘 저는 확인해 볼 가치가 있다고 생각되는 몇 가지 데코레이터를 보여드리고 싶습니다.
많은 데코레이터가 있지만 가장 멋진 기능을 가지고 있다고 생각되는 몇 가지를 골랐습니다.
이 목록의 첫 번째 데코레이터는 functools 모듈에서 나옵니다.
이 모듈은 표준 라이브러리에 포함되어 있으며 사용하기 매우 쉽습니다. 또한 이 데코레이터보다 더 멋진 기능이 포함되어 있지만 이 데코레이터는 확실히 제가 가장 좋아하는 것입니다.
이 데코레이터는 캐싱을 사용하여 함수의 연속 실행 속도를 높이는 데 사용할 수 있습니다. 물론 캐싱에 대한 몇 가지 주의 사항을 염두에 두고 사용해야 하지만 일반적인 사용 사례에서는 대부분 이 데코레이터를 사용할 가치가 있습니다.
간단한 데코레이터를 사용하여 코드 속도를 높일 수 있다는 것은 정말 멋진 일입니다.
이러한 데코레이터의 이점을 얻을 수 있는 함수의 좋은 예는 계승을 계산하는 함수와 같은 재귀 함수입니다.
def factorial(n): return n * factorial(n-1) if n else 1
재귀는 계산 시간 측면에서 매우 어려울 수 있지만 이 데코레이터를 추가하면 다음을 보여주는 데 도움이 됩니다. 이 기능의 연속 작동 속도를 높이기 위해.
@lru_cache def factorial(n): return n * factorial(n-1) if n else 1
이제 이 함수를 실행할 때마다 처음 몇 가지 계승 계산이 캐시에 저장됩니다.
다음에 이 함수를 호출할 때는 이전에 사용한 계승값을 계산한 후 계승값만 계산하면 됩니다.
물론 모든 계승 계산이 저장되는 것은 아니지만 이 데코레이터가 자연스럽게 느린 코드의 속도를 높이는 데 좋은 애플리케이션인 이유를 쉽게 알 수 있습니다.
JIT는 Just In Time의 약자입니다. 일반적으로 Python에서 일부 코드를 실행할 때마다 가장 먼저 일어나는 일은 컴파일입니다.
이 컴파일은 유형이 메모리를 할당하고 할당되지 않았지만 이름이 지정된 별칭으로 저장되기 때문에 약간의 오버헤드를 발생시킵니다. JIT(Just-In-Time) 컴파일을 사용하면 실행 시에만 컴파일합니다.
여러 면에서 이것을 Python 인터프리터가 시간을 절약하기 위해 두 가지 작업을 동시에 처리하는 병렬 컴퓨팅과 비슷한 것으로 생각할 수 있습니다.
Numba JIT 컴파일러는 이 개념을 Python에 도입한 것으로 유명합니다. @lru_cache와 마찬가지로 이 데코레이터는 매우 쉽게 호출할 수 있으며 즉시 코드 성능을 향상시킵니다. Numba 패키지는 C를 사용하지 않고도 보다 집약적인 소프트웨어를 더 쉽게 실행할 수 있게 해주는 jit 데코레이터를 제공합니다.
다음 사례에서는 @jit 데코레이터를 사용하여 Monte Carlo 방법 계산을 가속화합니다.
from numba import jit import random @jit(nopython=True) def monte_carlo_pi(nsamples): acc = 0 for i in range(nsamples): x = random.random() y = random.random() if (x ** 2 + y ** 2) < 1.0: acc += 1 return 4.0 * acc / nsamples
do_twice 데코레이터는 이름에서 알 수 있는 것과 정확히 일치합니다. 이 데코레이터를 사용하면 한 번의 호출로 함수를 두 번 실행할 수 있습니다. 이것은 확실히 몇 가지 용도가 있으며 특히 디버깅에 유용하다고 생각합니다.
두 가지 다른 반복의 성능을 측정하는 데 사용할 수 있습니다. Functools를 예로 들면, 기능을 두 번 실행하여 개선 사항을 확인할 수 있습니다. 이 함수는 표준 라이브러리에 있는 Python의 데코레이터 모듈에서 제공됩니다.
from decorators import do_twice @do_twice def timerfunc(): %timeit factorial(15)
count_calls 데코레이터는 소프트웨어에서 함수가 몇 번 사용되는지에 대한 정보를 제공하는 데 사용할 수 있습니다.
do_twice처럼 디버깅할 때 확실히 유용할 수 있습니다.
특정 함수에 추가되면 함수가 실행될 때마다 함수가 몇 번 실행되었는지 알려주는 출력을 받게 됩니다. 이 데코레이터는 표준 라이브러리의 데코레이터 모듈에도 있습니다.
from decorators import count_calls @count_calls def function_example(): print("Hello World!") function_example() function_example() function_example()
수업 작성 시간을 절약하기 위해 제가 사용해 본 최고의 데코레이터 중 하나는 @dataclass 데코레이터입니다.
이 데코레이터는 우리가 작성하는 클래스에서 일반적으로 발견되는 클래스의 일반적인 표준 메소드를 빠르게 작성하는 데 사용할 수 있습니다.
이 데코레이터는 dataclass 모듈에서 나옵니다. 이 모듈은 표준 라이브러리에도 있으므로 이 예제를 시도하는 데 PIP가 필요하지 않습니다!
from dataclasses import dataclass @dataclass class Food: name: str unit_price: float stock: int = 0 def stock_value(self) -> float: return(self.stock * self.unit_price)
이 코드는 클래스의 데이터를 채우는 데 필요한 위치 매개변수를 사용하여 초기화 함수 init()를 자동으로 생성합니다.
또한 자체적으로 자동으로 제공되므로 일부 데이터 매개변수를 클래스에 넣기 위해 긴 함수를 작성할 필요가 없습니다.
싱글턴 데코레이터의 목적을 이해하려면 먼저 싱글턴이 무엇인지 이해해야 합니다. 어떤 의미에서 싱글톤은 전역 변수 유형의 버전입니다.
这意味着类型被定义为只存在一次。尽管这些在 C++ 等语言中很常见,但在 Python 中却很少见到。使用单例,我们可以创建一个只使用一次的类并改变类,而不是通过初始化来构造新的类型。
通常,单例装饰器是由用户自己编写的,实际上并不是导入的。
这是因为单例仍然是对我们单例装饰器中提供的模板的引用。我们可以命名一个单例函数并编写一个包装器,以便在我们的类上使用这个装饰器:
def singleton(cls): instances = {} def wrapper(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return wrapper @singleton class cls: def func(self):
另一种方法是使用元类!
在科学计算中经常派上用场的一种装饰器是 @use_unit 装饰器。
此装饰器可用于更改返回结果的表示单位。这对于那些不想在数据中添加度量单位但仍希望人们知道这些单位是什么的人很有用。
这个装饰器也不是在任何模块中真正可用,但它是非常常见的,对科学应用程序非常有用。
def use_unit(unit): """Have a function return a Quantity with given unit""" use_unit.ureg = pint.UnitRegistry() def decorator_use_unit(func): @functools.wraps(func) def wrapper_use_unit(*args, **kwargs): value = func(*args, *_kwargs) return value _ use_unit.ureg(unit) return wrapper_use_unit return decorator_use_unit @use_unit("meters per second") def average_speed(distance, duration): return distance / duration
Functools 凭借非常有用的@singledispatch 装饰器再次在此列表中脱颖而出。
单调度是一种编程技术,在许多编程语言中都很常见,因为它是一种非常棒的编程方式。虽然我更喜欢多调度,但我认为单调度可以在很多方面扮演相同的角色。
这个装饰器使得在 Python 中使用多类型数据变得更加容易, 尤其当我们希望通过同一方法传递多种类型数据时,情况更是如此。
@singledispatch def fun(arg, verbose=False): if verbose: print("Let me just say,", end=" ") print(arg) @fun.register def _(arg: int, verbose=False): if verbose: print("Strength in numbers, eh?", end=" ") print(arg) @fun.register def _(arg: list, verbose=False): if verbose: print("Enumerate this:") for i, elem in enumerate(arg): print(i, elem)
위 내용은 엄청난! 멋진 Python 데코레이터 8개를 추천해 주세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!