File: funcs.rst

package info (click to toggle)
python-funcy 2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 536 kB
  • sloc: python: 2,989; makefile: 140; javascript: 96; sh: 6
file content (186 lines) | stat: -rw-r--r-- 5,303 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
Functions
=========

.. function:: identity(x)

    Returns its argument.


.. function:: constantly(x)

    Returns function accepting any args, but always returning ``x``.


.. function:: caller(*args, **kwargs)

    Returns function calling its argument with passed arguments.


.. function:: partial(func, *args, **kwargs)

    Returns partial application of ``func``. A re-export of :func:`py3:functools.partial`. Can be used in a variety of ways. DSLs is one of them::

        field = dict
        json_field = partial(field, json=True)


.. function:: rpartial(func, *args)

    Partially applies last arguments in ``func``::

        from operator import div
        one_third = rpartial(div, 3.0)

    Arguments are passed to ``func`` in the same order as they came to :func:`rpartial`::

        separate_a_word = rpartial(str.split, ' ', 1)


.. function:: func_partial(func, *args, **kwargs)

    Like :func:`partial` but returns a real function. Which is useful when, for example, you want to create a method of it::

        setattr(self, 'get_%s_display' % field.name,
                func_partial(_get_FIELD_display, field))

    Use :func:`partial` if you are ok to get callable object instead of function as it's faster.


.. function:: curry(func[, n])

    Curries function. For example, given function of two arguments ``f(a, b)`` returns function::

        lambda a: lambda b: f(a, b)

    Handy to make a partial factory::

        make_tester = curry(re_test)
        is_word = make_tester(r'^\w+$')
        is_int = make_tester(r'^[1-9]\d*$')

    But see :func:`re_tester` if you need this particular one.


.. function:: rcurry(func[, n])

    Curries function from last argument to first::

        has_suffix = rcurry(str.endswith, 2)
        lfilter(has_suffix("ce"), ["nice", "cold", "ice"])
        # -> ["nice", "ice"]

    Can fix number of arguments when it's ambiguous::

        to_power = rcurry(pow, 2) # curry 2 first args in reverse order
        to_square = to_power(2)
        to_cube = to_power(3)


.. function:: autocurry(func)

    Constructs a version of ``func`` returning its partial applications until sufficient arguments are passed::

        def remainder(what, by):
            return what % by
        rem = autocurry(remainder)

        assert rem(10, 3) == rem(10)(3) == rem()(10, 3) == 1
        assert map(rem(by=3), range(5)) == [0, 1, 2, 0, 1]

    Can clean your code a bit when :func:`partial` makes it too cluttered.


.. function:: compose(*fs)

    Returns composition of functions::

        extract_int = compose(int, r'\d+')

    Supports :ref:`extended_fns`.


.. function:: rcompose(*fs)

    Returns composition of functions, with functions called from left to right. Designed to facilitate transducer-like pipelines::

        # Note the use of iterator function variants everywhere
        process = rcompose(
            partial(remove, is_useless),
            partial(map, process_row),
            partial(chunks, 100)
        )

        for chunk in process(data):
            write_chunk_to_db(chunk)

    Supports :ref:`extended_fns`.


.. function:: juxt(*fs)
              ljuxt(*fs)

    Takes several functions and returns a new function that is the juxtaposition of those. The resulting function takes a variable number of arguments, and returns an iterator or a list containing the result of applying each function to the arguments.


.. function:: iffy([pred], action, [default=identity])

    Returns function, which conditionally, depending on ``pred``, applies ``action`` or  ``default``. If ``default`` is not callable then it is returned as is from resulting function. E.g. this will call all callable values leaving rest of them as is::

        map(iffy(callable, caller()), values)

    Common use it to deal with messy data::

        dirty_data = ['hello', None, 'bye']
        lmap(iffy(len), dirty_data)              # => [5, None, 3]
        lmap(iffy(isa(str), len, 0), dirty_data) # => [5, 0, 3], also safer

    See also :func:`silent` for easier use cases.


Function logic
--------------

This family of functions supports creating predicates from other predicates and regular expressions.


.. function:: complement(pred)

    Constructs a negation of ``pred``, i.e. a function returning a boolean opposite of original function::

        is_private = re_tester(r'^_')
        is_public = complement(is_private)

        # or just
        is_public = complement(r'^_')


.. function:: all_fn(*fs)
              any_fn(*fs)
              none_fn(*fs)
              one_fn(*fs)

    Construct a predicate returning ``True`` when all, any, none or exactly one of ``fs`` return ``True``. Support short-circuit behavior.

    ::

        is_even_int = all_fn(isa(int), even)



.. function:: some_fn(*fs)

    Constructs function calling ``fs`` one by one and returning first true result.

    Enables creating functions by short-circuiting several behaviours::

        get_amount = some_fn(
            lambda s: 4 if 'set of' in s else None,
            r'(\d+) wheels?',
            compose({'one': 1, 'two': 2, 'pair': 2}, r'(\w+) wheels?')
        )

    If you wonder how on Earth one can :func:`compose` dict and string see :ref:`extended_fns`.


.. raw:: html
    :file: descriptions.html