Skip to content

Commit c7aeebf

Browse files
committed
Further simplified: got rid of the useless inner make_lambda_friendly_method. Now Constant() is used all over the place, even for methods.
1 parent 85906c5 commit c7aeebf

File tree

1 file changed

+7
-116
lines changed

1 file changed

+7
-116
lines changed

mini_lambda/base.py

Lines changed: 7 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -219,127 +219,18 @@ def constant(cls, value: T, name: str = None) -> Union[T, Any]: # Any really me
219219

220220
elif callable(value):
221221
# a function
222-
return cls.make_lambda_friendly_method(value, name=name)
222+
# If the provided method does not have a name then name is mandatory
223+
if (not hasattr(value, '__name__') or value.__name__ == '<lambda>') and name is None:
224+
raise ValueError('This method does not have a name (it is either a partial or a lambda) so you have to '
225+
'provide one: the \'name\' argument is mandatory')
226+
227+
# return cls.make_lambda_friendly_method(value, name=name)
228+
return cls(str_expr=name or value.__name__, is_constant=True, constant_value=value)
223229

224230
else:
225231
# a true 'constant'
226232
return cls(str_expr=name or str(value), is_constant=True, constant_value=value)
227233

228-
@classmethod
229-
def make_lambda_friendly_method(cls, method: Callable, name: str = None):
230-
"""
231-
Utility method to transform any method whatever their signature (positional and/or keyword arguments,
232-
variable-length included) into a method usable inside lambda expressions, even if some of the arguments are
233-
expressions themselves.
234-
235-
In particular you may wish to convert:
236-
237-
* standard or user-defined functions. Note that by default the name appearing in the expression is func.__name__
238-
239-
```python
240-
from mini_lambda import x, _, make_lambda_friendly_method
241-
from math import log
242-
243-
# transform standard function `log` into lambda-friendly function `Log`
244-
Log = make_lambda_friendly_method(log)
245-
246-
# now you can use it in your lambda expressions
247-
complex_identity = _( Log(10 ** x, 10) )
248-
complex_identity(3.5) # returns 3.5
249-
print(complex_identity) # "log(10 ** x, 10)"
250-
```
251-
252-
* anonymous functions such as lambdas and partial. In which case you HAVE to provide a name
253-
254-
```python
255-
from mini_lambda import x, _, make_lambda_friendly_method
256-
from math import log
257-
258-
# ** partial function (to fix leftmost positional arguments and/or keyword arguments)
259-
from functools import partial
260-
is_superclass_of_bool = make_lambda_friendly_method(partial(issubclass, bool), name='is_superclass_of_bool')
261-
262-
# now you can use it in your lambda expressions
263-
expr = _(is_superclass_of_bool(x))
264-
expr(int) # True
265-
expr(str) # False
266-
print(expr) # "is_superclass_of_bool(x)"
267-
268-
# ** lambda function
269-
Log10 = make_lambda_friendly_method(lambda x: log(x, 10), name='log10')
270-
271-
# now you can use it in your lambda expressions
272-
complex_identity = _(Log10(10 ** x))
273-
complex_identity(3.5) # 3.5
274-
print(complex_identity) # "log10(10 ** x)"
275-
```
276-
277-
* class functions. Note that by default the name appearing in the expression is func.__name__
278-
279-
```python
280-
from mini_lambda import x, _, make_lambda_friendly_method
281-
282-
# ** standard class function
283-
StartsWith = make_lambda_friendly_method(str.startswith)
284-
285-
# now you can use it in your lambda expressions
286-
str_tester = _(StartsWith('hello', 'el', x))
287-
str_tester(0) # False
288-
str_tester(1) # True
289-
print(str_tester) # "startswith('hello', 'el', x)"
290-
291-
# ** static and class functions
292-
class Foo:
293-
@staticmethod
294-
def bar1(times, num, den):
295-
return times * num / den
296-
297-
@classmethod
298-
def bar2(cls, times, num, den):
299-
return times * num / den
300-
301-
FooBar1 = make_lambda_friendly_method(Foo.bar1)
302-
fun1 = _( FooBar1(x, den=x, num=1) )
303-
304-
FooBar2a = make_lambda_friendly_method(Foo.bar2) # the `cls` argument is `Foo` and cant be changed
305-
fun2a = _( FooBar2a(x, den=x, num=1) )
306-
307-
FooBar2b = make_lambda_friendly_method(Foo.bar2.__func__) # the `cls` argument can be changed
308-
fun2b = _( FooBar2b(Foo, x, den=x, num=1) )
309-
```
310-
311-
Note: although the above is valid, it is much more recommended to convert the whole class
312-
313-
314-
:param method:
315-
:param name: an optional name for the method when used to display the expressions. It is mandatory if the method
316-
does not have a name, otherwise the default name is method.__name__
317-
:return:
318-
"""
319-
320-
# If the provided method does not have a name then name is mandatory
321-
if (not hasattr(method, '__name__') or method.__name__ == '<lambda>') and name is None:
322-
raise ValueError('This method does not have a name (it is either a partial or a lambda) so you have to '
323-
'provide one: the \'name\' argument is mandatory')
324-
325-
# create a named method if a new name is provided
326-
if name is not None:
327-
# work on a copy to rename it
328-
def new_method(*args, **kwargs):
329-
return method(*args, **kwargs)
330-
331-
new_method.__name__ = name
332-
else:
333-
new_method = method
334-
335-
# construct the lambda-friendly method
336-
def lambda_friendly_method(*args, **kwargs):
337-
""" A replacement method for `method`, that returns a new expression corresponding to executing the inner
338-
method with the provided arguments """
339-
return cls._get_expression_for_method_with_args(new_method, *args, **kwargs)
340-
341-
return lambda_friendly_method
342-
343234
@classmethod
344235
def _get_expression_for_method_with_args(cls, method, *args, **kwargs):
345236
"""

0 commit comments

Comments
 (0)