Tujuan utama dari posting ini adalah untuk menunjukkan satu pola arsitektur yang jarang digunakan dalam Python yang disebut " inti fungsional - pembungkus imperatif ", di mana pemrograman fungsional dicampur dengan pemrograman imperatif dalam upaya untuk meniadakan kekurangan masing-masing. Bahasa fungsional diketahui lemah saat berinteraksi dengan "dunia nyata", seperti input pengguna, interaksi GUI, atau I / O lainnya.
Pendekatan ini menggunakan kemampuan Python untuk bekerja dengan fungsi dalam paradigma fungsional, di mana fungsi dapat dimanipulasi dengan cara yang sama seperti objek lainnya: diteruskan sebagai argumen ke fungsi lain, dikembalikan dari fungsi, dan disertakan dalam urutan sebagai elemennya.
Bagi mereka yang ingin mempelajari pemrograman fungsional dengan Python, saya sarankan mengikuti tautan ke posting saya tentang dasar-dasar FP dengan Python.
Gaya pemrograman fungsional sangat mirip dengan bagaimana seseorang berpikir sambil memecahkan masalah. βBiarlah diberikan x
. Untuk menyelesaikan masalah dengan data ini, perlu dilakukan serangkaian transformasi. Pertama, terapkan ke mereka f
dan dapatkan data yang dihasilkan x'
. Kemudian terapkan ke data baru f2
dan dapatkan data baru yang dihasilkan x''
, dll.
, . , .. . , . , (), .
, , (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. . , , , .