Created
June 6, 2023 21:36
-
-
Save shreve/fdc1a3f90dee8b2c130748fc98b26f32 to your computer and use it in GitHub Desktop.
Lazy evaluation wrapper for python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Callable, Generic, TypeVar, Any | |
Type = TypeVar("Type") | |
class Lazy(Generic[Type]): | |
""" | |
Define a lazily-evaluated value. The function will only be called once, and the | |
container will invisibly act like the value. | |
""" | |
def __init__(self, func: Callable[[], Type]): | |
self.__func__ = func | |
def __repr__(self): | |
return self.__value__.__repr__() | |
def __getattribute__(self, name: str) -> Any: | |
try: | |
# First, try to get the attribute from the container itself. | |
return super(Lazy, self).__getattribute__(name) | |
except AttributeError: | |
# If that fails, try to get it from the value. | |
if "__value__" not in self.__dict__: | |
self.__value__ = self.__func__() | |
del self.__func__ | |
# In the case where lazy.value is the attribute which triggers eval, we | |
# need to return the value itself rather than get the attribute from it. | |
if name == "__value__": | |
return self.__value__ | |
# Otherwise, send every other request to the value. | |
return self.__value__.__getattribute__(name) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from .lazy import Lazy | |
def approximate_pi(n: int) -> float: | |
"""Approximate pi using the Gregory-Leibniz series.""" | |
return 4 * sum( | |
(-1) ** k / (2 * k + 1) for k in range(n) | |
) | |
# Completes instantly | |
pi = Lazy(lambda: approximate_pi(10_000_000)) | |
# First access takes several seconds | |
pi | |
# Second access is instant | |
pi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment