この投稿の主な目標は、「関数型コア-命令型ラッパー」と呼ばれるPythonでほとんど使用されないアーキテクチャパターンを示すことです。このパターンでは、関数型プログラミングと命令型プログラミングを組み合わせて、それぞれの欠点を打ち消そうとします。関数型言語は、ユーザー入力、GUIインタラクション、その他のI / Oなど、「現実の世界」と対話するときに弱いことが知られています。
このアプローチでは、関数パラダイム内の関数を操作するPythonの機能を使用します。この場合、関数は他のオブジェクトと同じように操作できます。つまり、他の関数に引数として渡され、関数から返され、要素としてシーケンスに含まれます。
Pythonで関数型プログラミングをブラッシュアップしたい方は、PythonでのFPの基本に関する私の投稿へのリンクをたどることをお勧めします。
プログラミングの機能的なスタイルは、問題を解決する際の人の考え方に非常に近いものです。「与えましょうx
。このデータの問題を解決するには、一連の変換を実行する必要があります。まず、それらに適用しf
、結果のデータを取得しますx'
。次に、新しいデータに適用して、f2
新しい結果データx''
などを取得します。
, . , .. . , . , (), .
, , (1) (2) , debug, (3) , .
, . F#:
2
|> ( fun x -> x + 5)
|> ( fun x -> x * x)
|> ( fun x -> x.ToString() )
, 2, -. Python, , , , :
#
def pipe(data, *fseq):
for fn in fseq:
data = fn(data)
return data
Python:
pipe(2,
lambda x: x + 5,
lambda x: x * x,
lambda x: str(x))
:
add = lambda x: lambda y: x + y
square = lambda x: x * x
tostring = lambda x: str(x)
pipe(2,
add(5),
square,
tostring)
2 , '49'
. reduce
, , pipe .
pipe
: data
fseq
. for
. , data . .. , . pipe . .
. pipe *
. *
.
, , . ,
def my_sum(*args): #
return sum(args)
my_sum(1, 2, 3, 4, 5)
. ,
def fun(a, b, c, d):
print(a, b, c, d)
my_list = [1, 2, 3, 4]
fun(*my_list) #
class Factory:
def process(self, input):
raise NotImplementedError
class Extract(Factory):
def process(self, input):
print(" ...")
output = {}
return output
class Parse(Factory):
def process(self, input):
print(" ...")
output = {}
return output
class Load(Factory):
def process(self, input):
print(" ...")
output = {}
return output
pipe = {
"" : Extract(),
"" : Parse(),
"" : Load(),
}
inputs = {}
#
for name, instance in pipe.items():
inputs = instance.process(inputs)
:
... ... ...
for
, . - , . « , , , » - , - Erlang.
, , , .
(factorial
) (factorial_rec
). . , . .
, , - ;-), .. .
#
#
def main():
# ( c )
pipe(int(input(' : ')),
lambda n: (n, reduce(lambda x, y: x * y, range(1, n + 1))),
lambda tup:
print(f' {tup[0]} {tup[1]}'))
#
main()
:
: 4 (Enter)
4 24
- , .
, .. - - . . .
#
#
def get_int(msg=''):
return int(input(msg))
def main():
# 1.
def factorial_rec(n):
fn = lambda n, acc=1: acc if n == 0 else fn(n - 1, acc * n)
return n, fn(n)
# 2.
def factorial(n):
return n, reduce(lambda x, y: x * y, range(1, n + 1))
#
def indata():
def validate(n): #
if not isinstance(n, int):
raise TypeError(" .")
if not n >= 0:
raise ValueError(" >= 0.")
return n
msg = ' : '
return pipe(get_int(msg), validate)
#
def outdata():
def fn(data):
n, fact = data
print(f' {n} {fact}')
return fn
# ( )
pipe(indata(), # : - : int
factorial, # : int :
outdata()) # : : -
#
main()
:
: 4 (Enter)
4 24
:
pipe(indata(), factorial, outdata())
, .. indata
, factorial
outdata
. indata
, . factorial
, , , . outdata
. , indata , .
. -, - . -, .
:
. ,
factorial
,factorial_rec
.
pipe(indata(), factorial_rec, outdata())
, .
, – . debug
:
def debug(data):
print(data)
return data
, :
pipe(indata(), debug, factorial, debug, outdata())
, :
:
: 4 (Enter)
4
(4, 24)
4 24
, factorial
4
, (4, 24)
. , , . , debug
-, .
.
#
#
def main():
#
def fibonacci(n, x=0, y=1):
# fib n- .
fib = lambda n, x=0, y=1: x if n <= 0 else fib(n - 1, y, x + y)
# reduce acc
acc = []
reduce(lambda _, y: acc.append(fib(y)), range(n + 1))
return n, acc
#
def validate(n):
if not isinstance(n, int):
raise TypeError(" .")
if not n >= 0:
raise ValueError(" .")
if n > 10:
raise ValueError(" 10.")
return n
#
def indata():
msg = ' 10: '
return pipe(get_int(msg), validate)
#
def outdata():
def fn(data):
n, seq = data
msg = f' {n} :'
print(msg)
[print(el) for el in seq]
return fn
# ( )
pipe(indata(), fibonacci, outdata())
# .
main()
10: 10 (Enter)
10 :
1
1
2
3
5
8
13
21
34
55
#
#
#
def main():
#
def range_sum(data):
seq, params = data
fn = lambda start, end: 0 if start > end \
else seq[start] + fn(start + 1, end)
return fn(*params)
#
def indata():
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
params = (2,5) # params - start, end
return seq, params
#
def outdata():
def f(data):
msg = ' 2 5 '
print(msg, format(data), sep='')
return f
# ( )
pipe(indata(), range_sum, outdata())
# .
main()
2 5 18
Python . : . . , , , , , . , .)
Github. Strating Out with Python. , . ,
-
-
Youtube « Python - ».
, , Python , map/filter/reduce/zip functools. . , , , .