
Einer der Hauptvorteile von Python ist seine Ausdruckskraft. Die Funktionalität der Sprache ermöglicht es Ihnen, Transformationen über Daten präzise zu beschreiben. Meiner Meinung nach fehlen in Python einige Tools, mit denen Datentransformationen bequemer beschrieben und die Funktionskomponente der Sprache ergänzt werden können, insbesondere "Funktionspipelines" und deren teilweise Anwendung. Daher gieße ich in diesem Beitrag Wasser auf die Möglichkeit und Notwendigkeit dieser Mittel mit Experimenten für ihre Umsetzung. Ich bin auf viele Arten zur Kritik gekommen. Viel Spaß beim Lesen!
Kurz über FP in Python und warum es zum Beispiel nicht genug Pipelines gibt
Python verfügt über einige nützliche Basiswerkzeuge wie map (), redu (), filter (), Lambda-Funktionen, Iteratoren und Generatoren. Ich rate allen, die mit diesem Artikel nicht vertraut sind . Im Allgemeinen können Sie damit Transformationen über Listen, Tupel usw. schnell und natürlich beschreiben. Sehr oft (mit mir und meinen Freunden Pythonisten) was sich herausstelltEinzeiler- im Wesentlichen eine Reihe von sequentiellen Transformationen, Filter, zum Beispiel:
Kata mit CodeWars : Find
, ( ), .
:
def sum_dig_pow(a, b): # range(a, b + 1) will be studied by the function
powered_sum = lambda x: sum([v**(i+1) for i,v in enumerate(map(lambda x: int(x), list(str(x))))])
return [i for i in range(a,b+1) if powered_sum(i)==i]
" ". .
( "|" — ):
# f3(f2(f1(x)))
f1 | f2 | f3 >> x
pipeline = f1 | f2 | f3
pipeline(x)
pipeline2 = f4 | f5
pipeline3 = pipeline | pipeline2 | f6
...
powered_sum ( ):
powered_sum = str | list | map(lambda x: int(x), *args) | enumerate | [v**(i+1) for i,v in *args] | sum
, . args . , ( ):
from copy import deepcopy
class CreatePipeline:
def __init__(self, data=None):
self.stack = []
if data is not None:
self.args = data
def __or__(self, f):
new = deepcopy(self)
new.stack.append(f)
return new
def __rshift__(self, v):
new = deepcopy(self)
new.args = v
return new
def call_logic(self, *args):
for f in self.stack:
if type(args) is tuple:
args = f(*args)
else:
args = f(args)
return args
def __call__(self, *args):
if 'args' in self.__dict__:
return self.call_logic(self.args)
else:
return self.call_logic(*args)
, , , kwargs, .
pipe = CreatePipeline()
powered_sum = pipe | str | list | (lambda l: map(lambda x: int(x), l)) | enumerate | (lambda e: [v**(i+1) for i,v in e]) | sum
, , , , , .
( ):
def f_partitial (x,y,z):
return x+y+z
v = f_partial(1,2)
# type(v) = - f_partial, : ['z']
print(v(3))
#
print(f_partial(1,2,3))
( ). pipe :
powered_sum = pipe | str | list | map(lambda x: int(x)) | enumerate | (lambda e: [v**(i+1) for i,v in e]) | sum
# map
# map(lambda x: int(x))()
map(lambda x: int(x)) .
:
from inspect import getfullargspec
from copy import deepcopy
class CreatePartFunction:
def __init__(self, f):
self.f = f
self.values = []
def __call__(self, *args):
args_f = getfullargspec(self.f)[0]
if len(args) + len(self.values) < len(args_f):
new = deepcopy(self)
new.values = new.values + list(args)
return new
elif len(self.values) + len(args) == len(args_f):
return self.f(*tuple(self.values + list(args)))
:
# inspect map
m = lambda f, l: map(f, l)
#
pmap = CreatePartFunction(m)
powered_sum = pipe | str | list | pmap(lambda x: int(x)) | enumerate | (lambda e: [v**(i+1) for i,v in e]) | sum
( ), , , , :
def f (x,y,z):
return x+y+z
f = CreatePartFunction(f)
#
print(f(1,2,3))
#
print(f(1,2)(3))
print(f(1)(2,3))
#
# 2(3) - int callable
print(f(1)(2)(3))
#
print((f(1)(2))(3))
, , , , , , , .