関数合成的な何か
$ python -V
Python 3.8.6
a.py
import functools
class F:
@staticmethod
def __cmp(f1, f2):
def __i1(*args1, **kwargs1):
def __i2(*args2, **kwargs2):
return f1(*args2, **kwargs2)
return f2(__i2(*args1, **kwargs1))
return __i1
@classmethod
def composite(cls, *fs):
return functools.reduce(cls.__cmp, fs)
test
a_test.py
import pytest
import functools
from a import F
def test_args1():
"""1引数の関数合成"""
def d1(a):
r = a * 2
print(f"d1: {a} * 2 = {r}")
return r
def d2(a):
r = a + 1
print(f"d2: {a} + 1 = {r}")
return r
def d3(a):
r = a // 3
print(f"d3: {a} / 3 = {r}")
return r
f = F.composite(d1, d2, d3, d1, d2)
assert f(123) == 165
def test_args2():
"""2引数以上はできないので適当にカリー化するとよい"""
def d1(a, b):
r = a * b
print(f"d1: {a} * {b} = {r}")
return r
def d2(a, b):
r = a + b
print(f"d2: {a} + {b} = {r}")
return r
d3 = functools.partial(d1, b=2)
d4 = functools.partial(d2, b=1)
d5 = functools.partial(d1, b=3)
d6 = functools.partial(d2, b=4)
f = F.composite(d3, d4, d5, d6)
assert f(123) == 745
def test_args3():
"""2引数以上は(ry"""
def d1(a, b, c):
r = a // b - c
print(f"d1: {a} // {b} - {c} = {r}")
return r
def d2(a, b, c):
r = (a + b) ** c
print(f"d2: ({a} + {b}) ** {c} = {r}")
return r
d3 = functools.partial(d1, b=5, c=5)
d4 = functools.partial(d2, b=3, c=2)
d5 = functools.partial(d1, b=345, c=3)
d6 = functools.partial(d2, b=4, c=8)
f = F.composite(d3, d4, d5, d6)
assert f(123) == 256
run test
bash
$ pytest -V
pytest 6.1.2
$ pytest -s -v a_test.py
=============================================== test session starts ===============================================
platform darwin -- Python 3.8.6, pytest-6.1.2, py-1.9.0, pluggy-0.13.1 -- /Users/kuryu/.pyenv/versions/3.8.6/bin/python3.8
cachedir: .pytest_cache
rootdir: /Users/kuryu/workspace/work
plugins: Faker-4.16.0
collected 3 items
a_test.py::test_args1 d1: 123 * 2 = 246
d2: 246 + 1 = 247
d3: 247 / 3 = 82
d1: 82 * 2 = 164
d2: 164 + 1 = 165
PASSED
a_test.py::test_args2 d1: 123 * 2 = 246
d2: 246 + 1 = 247
d1: 247 * 3 = 741
d2: 741 + 4 = 745
PASSED
a_test.py::test_args3 d1: 123 // 5 - 5 = 19
d2: (19 + 3) ** 2 = 484
d1: 484 // 345 - 3 = -2
d2: (-2 + 4) ** 8 = 256
PASSED
================================================ 3 passed in 0.06s ================================================
カレー食べたい。