Reference
At the core of lazyfunc
is the LazyFunc
class. It makes operations
between callables and arbitrary datatypes possible, by deferring evaluation
to a later time.
The methods and properties of the LazyFunc
class are listed below.
LazyFunc
Operations between callables, with lazy evaluation.
Source code in lazyfunc/lazy_func.py
class LazyFunc(metaclass=LazyFuncMeta):
"""Operations between callables, with lazy evaluation."""
def __init__(self, func, description=None, **kwargs):
self.func = func
self._description = description
self._kwargs = self._default_kwargs = kwargs
self._precedence = None
@property
def __signature__(self):
return inspect.signature(self.func)
@property
def description(self) -> str:
"""Defaults to the name of the wrapped callable, but can be set by the user at
object initialisation. Also updated when operations are applied with other
callables.
Examples:
>>> def my_function(x):
... return x
>>> lf_auto = LazyFunc(my_function)
>>> lf_auto.description
'my_function'
>>> lf_named = LazyFunc(my_function, description='my_named_function')
>>> lf_named.description
'my_named_function'
Returns:
A string describing the wrapped function.
"""
if self._description is None:
return callable_name(self.func)
else:
return self._description
@property
def __name__(self) -> str:
"""Alias of the LazyFunc description."""
return self.description
def __repr__(self):
return f"{self.__class__.__name__}({self.description})"
def __call__(self, *args, **kwargs) -> object:
"""Either calls the wrapped function with the provided args and kwargs, or if
the first argument is a callable, returns a new LazyFunc object of
LazyFunc(args[0](self)).
When calling a LazyFunc instance, if the first argument is NOT a callable, it
behaves exactly as the unwrapped callable.
Examples:
>>> @LazyFunc
... def my_function(x):
... return 2 * x
...
>>> my_function('foo') # first argument is not callable
'foofoo'
>>> import builtins
>>> builtin_min = builtins.min
>>> min = LazyFunc(min)
>>> min([3, 1, 4, 1, 5, 9]) # first argument is not callable
1
>>> min('lazy', 'function', key=lambda s: s[1]) # first argument is
... # not callable
'lazy'
>>> min_of_my_function = min(my_function) # first argument is callable
>>> min_of_my_function
LazyFunc(min(my_function))
Args:
args: Positional arguments to be passed to wrapped function.
kwargs: Keyword arguments to be passed to wrapped function.
Returns: Either the result of the wrapped function evaluated with the
supplied args and _kwargs, or a new LazyFunc instance.
"""
if callable(args[0]):
operator_precedence = 17
other_func, *args = args
def new_func(*x):
return self.func(other_func(*x), *args, **kwargs)
new_desc = (
LazyFuncMeta._get_desc(self, operator_precedence)
+ "("
+ callable_name(other_func)
+ ")"
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator_precedence
return mf
else: # when the function is called the kwargs supplied to the call take
# precedence over those set elsewhere
final_kwargs = self._kwargs | kwargs
return self.func(*args, **final_kwargs)
def set_kwargs(self, **kwargs):
self._kwargs = kwargs
return self
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self._kwargs = self._default_kwargs
def is_equal(self, other: callable) -> bool:
"""Checks for equality between self and other.
To stay consistent with LazyFunc's other dunder methods, the `__eq__` method
lazily compares equality between the wrapped LazyFunc and other. Therefore,
this method exists to check whether two unevaluated LazyFunc objects are
equal, without calling them and comparing the results.
Examples:
>>> def my_function(x):
... return x
>>> lf_auto_1 = LazyFunc(my_function)
>>> lf_auto_2 = LazyFunc(my_function)
>>> lf_named = LazyFunc(my_function, description='my_named_function')
>>> lf_auto_1.is_equal(lf_auto_2)
True
>>> lf_auto_1.is_equal(lf_named)
False
"""
try:
equal = self.description == other.description
except AttributeError:
msg = "Can only compare a LazyFunc instance with another LazyFunc"
raise TypeError(msg)
if not equal:
msg = (
"LazyFunc descriptions found to be not equal though may still be "
"equivalent. "
)
warn(msg)
return equal
description: str
property
readonly
Defaults to the name of the wrapped callable, but can be set by the user at object initialisation. Also updated when operations are applied with other callables.
Examples:
>>> def my_function(x):
... return x
>>> lf_auto = LazyFunc(my_function)
>>> lf_auto.description
'my_function'
>>> lf_named = LazyFunc(my_function, description='my_named_function')
>>> lf_named.description
'my_named_function'
Returns:
Type | Description |
---|---|
str |
A string describing the wrapped function. |
__add__(*instances)
special
Return new instance LazyFunc(self + other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__and__(*instances)
special
Return new instance LazyFunc(self & other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__call__(self, *args, **kwargs)
special
Either calls the wrapped function with the provided args and kwargs, or if the first argument is a callable, returns a new LazyFunc object of LazyFunc(args0).
When calling a LazyFunc instance, if the first argument is NOT a callable, it behaves exactly as the unwrapped callable.
Examples:
>>> @LazyFunc
... def my_function(x):
... return 2 * x
...
>>> my_function('foo') # first argument is not callable
'foofoo'
>>> import builtins
>>> builtin_min = builtins.min
>>> min = LazyFunc(min)
>>> min([3, 1, 4, 1, 5, 9]) # first argument is not callable
1
>>> min('lazy', 'function', key=lambda s: s[1]) # first argument is
... # not callable
'lazy'
>>> min_of_my_function = min(my_function) # first argument is callable
>>> min_of_my_function
LazyFunc(min(my_function))
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Positional arguments to be passed to wrapped function. |
() |
|
kwargs |
Keyword arguments to be passed to wrapped function. |
{} |
Returns: Either the result of the wrapped function evaluated with the supplied args and _kwargs, or a new LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def __call__(self, *args, **kwargs) -> object:
"""Either calls the wrapped function with the provided args and kwargs, or if
the first argument is a callable, returns a new LazyFunc object of
LazyFunc(args[0](self)).
When calling a LazyFunc instance, if the first argument is NOT a callable, it
behaves exactly as the unwrapped callable.
Examples:
>>> @LazyFunc
... def my_function(x):
... return 2 * x
...
>>> my_function('foo') # first argument is not callable
'foofoo'
>>> import builtins
>>> builtin_min = builtins.min
>>> min = LazyFunc(min)
>>> min([3, 1, 4, 1, 5, 9]) # first argument is not callable
1
>>> min('lazy', 'function', key=lambda s: s[1]) # first argument is
... # not callable
'lazy'
>>> min_of_my_function = min(my_function) # first argument is callable
>>> min_of_my_function
LazyFunc(min(my_function))
Args:
args: Positional arguments to be passed to wrapped function.
kwargs: Keyword arguments to be passed to wrapped function.
Returns: Either the result of the wrapped function evaluated with the
supplied args and _kwargs, or a new LazyFunc instance.
"""
if callable(args[0]):
operator_precedence = 17
other_func, *args = args
def new_func(*x):
return self.func(other_func(*x), *args, **kwargs)
new_desc = (
LazyFuncMeta._get_desc(self, operator_precedence)
+ "("
+ callable_name(other_func)
+ ")"
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator_precedence
return mf
else: # when the function is called the kwargs supplied to the call take
# precedence over those set elsewhere
final_kwargs = self._kwargs | kwargs
return self.func(*args, **final_kwargs)
__eq__(*instances)
special
Return new instance LazyFunc(self == other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__floordiv__(*instances)
special
Return new instance LazyFunc(self // other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__ge__(*instances)
special
Return new instance LazyFunc(self >= other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__gt__(*instances)
special
Return new instance LazyFunc(self > other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__invert__(*instances)
special
Return new instance LazyFunc(~self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__le__(*instances)
special
Return new instance LazyFunc(self <= other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__lshift__(*instances)
special
Return new instance LazyFunc(self << other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__lt__(*instances)
special
Return new instance LazyFunc(self < other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__matmul__(*instances)
special
Return new instance LazyFunc(self @ other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__mod__(*instances)
special
Return new instance LazyFunc(self % other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__mul__(*instances)
special
Return new instance LazyFunc(self * other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__ne__(*instances)
special
Return new instance LazyFunc(self != other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__neg__(*instances)
special
Return new instance LazyFunc(-self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__or__(*instances)
special
Return new instance LazyFunc(self | other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__pos__(*instances)
special
Return new instance LazyFunc(+self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__pow__(*instances)
special
Return new instance LazyFunc(self ** other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__radd__(*instances)
special
Return new instance LazyFunc(other + self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rand__(*instances)
special
Return new instance LazyFunc(other & self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rfloordiv__(*instances)
special
Return new instance LazyFunc(other // self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rlshift__(*instances)
special
Return new instance LazyFunc(other << self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rmatmul__(*instances)
special
Return new instance LazyFunc(other @ self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rmod__(*instances)
special
Return new instance LazyFunc(other % self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rmul__(*instances)
special
Return new instance LazyFunc(other * self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__ror__(*instances)
special
Return new instance LazyFunc(other | self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rpow__(*instances)
special
Return new instance LazyFunc(other ** self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rrshift__(*instances)
special
Return new instance LazyFunc(other >> self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rshift__(*instances)
special
Return new instance LazyFunc(self >> other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rsub__(*instances)
special
Return new instance LazyFunc(other - self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rtruediv__(*instances)
special
Return new instance LazyFunc(other / self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__rxor__(*instances)
special
Return new instance LazyFunc(other ^ self), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__sub__(*instances)
special
Return new instance LazyFunc(self - other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__truediv__(*instances)
special
Return new instance LazyFunc(self / other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
__xor__(*instances)
special
Return new instance LazyFunc(self ^ other), where other may be a scalar value or any other callable including another LazyFunc instance.
Source code in lazyfunc/lazy_func.py
def inner(*instances):
new_func = LazyFuncMeta.new_function(operator, *instances)
new_func.__signature__ = LazyFuncMeta.build_new_signature(instances)
new_desc = LazyFuncMeta.description_from_operator(
operator, *instances, reverse=reverse
)
mf = LazyFunc(func=new_func, description=new_desc)
mf._precedence = operator.precedence
return mf
is_equal(self, other)
Checks for equality between self and other.
To stay consistent with LazyFunc's other dunder methods, the __eq__
method
lazily compares equality between the wrapped LazyFunc and other. Therefore,
this method exists to check whether two unevaluated LazyFunc objects are
equal, without calling them and comparing the results.
Examples:
>>> def my_function(x):
... return x
>>> lf_auto_1 = LazyFunc(my_function)
>>> lf_auto_2 = LazyFunc(my_function)
>>> lf_named = LazyFunc(my_function, description='my_named_function')
>>> lf_auto_1.is_equal(lf_auto_2)
True
>>> lf_auto_1.is_equal(lf_named)
False
Source code in lazyfunc/lazy_func.py
def is_equal(self, other: callable) -> bool:
"""Checks for equality between self and other.
To stay consistent with LazyFunc's other dunder methods, the `__eq__` method
lazily compares equality between the wrapped LazyFunc and other. Therefore,
this method exists to check whether two unevaluated LazyFunc objects are
equal, without calling them and comparing the results.
Examples:
>>> def my_function(x):
... return x
>>> lf_auto_1 = LazyFunc(my_function)
>>> lf_auto_2 = LazyFunc(my_function)
>>> lf_named = LazyFunc(my_function, description='my_named_function')
>>> lf_auto_1.is_equal(lf_auto_2)
True
>>> lf_auto_1.is_equal(lf_named)
False
"""
try:
equal = self.description == other.description
except AttributeError:
msg = "Can only compare a LazyFunc instance with another LazyFunc"
raise TypeError(msg)
if not equal:
msg = (
"LazyFunc descriptions found to be not equal though may still be "
"equivalent. "
)
warn(msg)
return equal
No inplace operators.
Note that there are no inplace operators available. This is because to do so requires
a new function to be created that depends on self
,
which is then assigned to self
. This is a problem because the wrapped functions are passed by reference rather
than by value, thus creating an infinite loop. One solution would be to create a copy of the old self
, however this uses the same amount of
memory as the non-inplace operation defeating the point. An alternative would be to simply call the non-inplace
operation with the inplace syntax, however this would then be misleading. As a result inplace operations are not
implemented for LazyFunc objects.