by Anonymous » 06 Jan 2025, 05:33
Code: Select all
from functools import wraps
from typing import Any, Callable, Generic, ParamSpec, TypeVar
T = TypeVar("T")
P = ParamSpec("P")
class LazyOp(Generic[T]):
def __init__(self, func: Callable[..., T], args: tuple[Any, ...], kwargs: dict[str, Any]):
self.func = func
self.args = args
self.kwargs = kwargs
def __call__(self) -> T:
args = [a() if isinstance(a, LazyOp) else a for a in self.args]
kwargs = {k: v() if isinstance(v, LazyOp) else v for k, v in self.kwargs.items()}
return self.func(*args, **kwargs)
def lazy_decorator(func: Callable[P, T]) -> Callable[P, LazyOp[T]]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> LazyOp[T]:
return LazyOp(func, args, kwargs)
return wrapper
@lazy_decorator
def lazy_sum(a: int, b: int) -> int:
return a + b
lazy_result = lazy_sum(1, 2)
lazy_result = lazy_sum(
lazy_result, 4
) # Argument of type "LazyOp[int]" cannot be assigned to parameter "a" of type "int". "LazyOp[int]" is not assignable to "int"
result = lazy_result()
print(result)
Wie aktiviere ich die automatische Unterstützung für Lazy-Argumente in mit @lazy_decorator dekorierten Funktionen mit mypy?
Ich brauche eine Möglichkeit, @lazy_decorator-Funktionen zu aktivieren, um:
- Ursprüngliche Typanmerkungen beibehalten: Funktionen sollten für mypy immer noch so aussehen, als ob sie ihre ursprünglichen Typen (z. B. int) akzeptieren und zurückgeben würden.
- Zulassen LazyOp-Argumente transparent: Dekorierte Funktionen sollten sowohl den Originaltyp (z. B. int) als auch seine Lazy-Variante (LazyOp[int]) akzeptieren, ohne Mypy-Fehler auszulösen.
- Manuelle Anpassungen vermeiden: Dies sollte der Fall sein Es ist nicht erforderlich, Typanmerkungen für jede dekorierte Funktion neu zu schreiben oder zusätzliche Wrapping-Typen in die Funktionssignatur einzuführen.
- Nahtlose Integration: Die Lösung sollte keine externen Plugins, keine größeren Umstrukturierungen usw. erfordern Dies opfert die Laufzeiteffizienz.
Im Wesentlichen möchte ich mypy „beibringen“, dass der Dekorator Argumenttypen erweitert, um ihre Lazy-Äquivalente einzuschließen und gleichzeitig das Original der Funktion beizubehalten Typanmerkung für Klarheit und Entwicklererfahrung.
[code]from functools import wraps
from typing import Any, Callable, Generic, ParamSpec, TypeVar
T = TypeVar("T")
P = ParamSpec("P")
class LazyOp(Generic[T]):
def __init__(self, func: Callable[..., T], args: tuple[Any, ...], kwargs: dict[str, Any]):
self.func = func
self.args = args
self.kwargs = kwargs
def __call__(self) -> T:
args = [a() if isinstance(a, LazyOp) else a for a in self.args]
kwargs = {k: v() if isinstance(v, LazyOp) else v for k, v in self.kwargs.items()}
return self.func(*args, **kwargs)
def lazy_decorator(func: Callable[P, T]) -> Callable[P, LazyOp[T]]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> LazyOp[T]:
return LazyOp(func, args, kwargs)
return wrapper
@lazy_decorator
def lazy_sum(a: int, b: int) -> int:
return a + b
lazy_result = lazy_sum(1, 2)
lazy_result = lazy_sum(
lazy_result, 4
) # Argument of type "LazyOp[int]" cannot be assigned to parameter "a" of type "int". "LazyOp[int]" is not assignable to "int"
result = lazy_result()
print(result)
[/code]
Wie aktiviere ich die automatische Unterstützung für Lazy-Argumente in mit @lazy_decorator dekorierten Funktionen mit mypy?
Ich brauche eine Möglichkeit, @lazy_decorator-Funktionen zu aktivieren, um:
[list]
[*]Ursprüngliche Typanmerkungen beibehalten: Funktionen sollten für mypy immer noch so aussehen, als ob sie ihre ursprünglichen Typen (z. B. int) akzeptieren und zurückgeben würden.
[*]Zulassen LazyOp-Argumente transparent: Dekorierte Funktionen sollten sowohl den Originaltyp (z. B. int) als auch seine Lazy-Variante (LazyOp[int]) akzeptieren, ohne Mypy-Fehler auszulösen.
[*]Manuelle Anpassungen vermeiden: Dies sollte der Fall sein Es ist nicht erforderlich, Typanmerkungen für jede dekorierte Funktion neu zu schreiben oder zusätzliche Wrapping-Typen in die Funktionssignatur einzuführen.
[*]Nahtlose Integration: Die Lösung sollte keine externen Plugins, keine größeren Umstrukturierungen usw. erfordern Dies opfert die Laufzeiteffizienz.
[/list]
Im Wesentlichen möchte ich mypy „beibringen“, dass der Dekorator Argumenttypen erweitert, um ihre Lazy-Äquivalente einzuschließen und gleichzeitig das Original der Funktion beizubehalten Typanmerkung für Klarheit und Entwicklererfahrung.