



нещо не мога да разбера идеята...може ли някой да ми разясни...
нещо не мога да разбера идеята...може ли някой да ми разясни...
Присъединявам се :)) Нали тия две звездички, са свързани със речник, а в примерчетата няма такова нещо. Нещо ми е много шантаво. И думи като частичното прилагане ме плашат :)
def tuplify(a, b, c): return (a, b, c) # връща n-торка от атрибутите си
curry(tuplify, 1, c = 3)(2) == (1, 2, 3) # True
curry(tuplify, 1, c = 3)(b = 2) == (1, 2, 3) # True
curry(tuplify, 1, c = 3)(2, c = 4) == (1, 2, 4) # True
curry(tuplify, 1, a = 3) # няма да има извиквания от този вид
този пример ме притеснява също, може ли да имама повече от един *args - нещо от сорта
curry(tuplify, 1,3,4 c = 3)(2, c = 4)
Забавни снимки.
редактирано
този пример ме притеснява също, може ли да имама повече от един *args - нещо от сорта
curry(tuplify, 1,3,4 c = 3)(2, c = 4)
По принцип може, но в случая тук се задават две стойности на c, веднъж като позиционен и веднъж като именован аргумент, което е невалидно. Също така curry задава стойности на всички позиционни аргументи, тогава върната функция не би трябвало да приема такива, но пък се прилага с 1 позиционен.
И по общо...
Имате функция на няколко аргумента - f(x, y, z)
. Искате да
зададете стойност на един от тях - x, напр. стойността 1, а другите да оставите
свободни.
g = curry(f, 1)
Получавате g(y, z)
, такава че за всяко y и за всяко z:
g(y, z) == f(1, y, z) # е вярно
Идеята на curry е да фиксирате част от аргументите, а другите да оставите свободни, така получавате функция на по-малък брой – свободните аргументи
Ако се ограничим до частният случай за функции на два аргумента:
# фиксира първият аргумент на 2 аргументната функция f
def curry1(f, x):
return lambda y: f(x, y)
# за всяко f, x, y имаме:
f(x, y) == curry1(f, x)(y) # е вярно
Разбира се тази версия няма да ви даде точки.
До тук фиксирахме позиционни аргументи. Python позволява и именовани
аргументи, и съответно искаме curry да може да фиксира и такива. Вижте
test_curry_kwargs
в примерния тест.
Също така това би ви било адски безполезно.
А забраната за import е, за да не използваме inspect?
Например.
А освен inspect, какви други начини има да определим колко аргумента взима функция, как help() определя с колко аргумента е дадена функция? Питам по принцип, не се отнася за тази задача.
inspect е съвсем нормален Python модул, който предоставя интерфейс към мета-информацията за живи обекти. Тази информация може да бъде достъпена и без inspect, но просто с чрез него е по-удобно. help използва inspect.
Иначе най-лесният начин да погледнеш какво има в обект е с dir:
>>> def afunc(a, b, c, *d, **e):
... return a, b, c, d, e
...
>>> dir(afunc)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',
'__defaults__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__',
'__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__',
'__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__']
>>> dir(afunc.__code__)
['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars',
'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags',
'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names',
'co_nlocals', 'co_stacksize', 'co_varnames']
>>> afunc.__code__.co_name
'afunc'
>>> afunc.__code__.co_names
()
>>> afunc.__code__.co_nlocals
5
>>> afunc.__code__.co_varnames
('a', 'b', 'c', 'd', 'e')
>>> afunc.__code__.co_varnames ('a', 'b', 'c', 'd', 'e')
Това е идеално, но не за всички функции. Например: map.__code__.co_varnames е невалидно...
Т.е. ако в някой от тестовете се подаде map на curry, ще загубим точки...
Освен това, ако приемем, че имаме функция от вида: def tuplify(a, b, c): d = 2 return (a, b, c, d)
tuplify.__code__.co_varnames връща ('a', 'b', 'c', 'd'), което е невалидно в контекста на условието. Т.е. ако подадете такава "специална" функция, отново нашата ще "гръмне".
Така че според мен въпросът остава отворен. За тези, които са предали задачите и са използвали този подход - моля опитайте да подадете map (или filter) и някаква "специална" функция като аргумент. Надявам се аз да съм се объркал нещо (ако е така sorry за спама).
В случая с curry инспекция не ти е необходима. Иначе може да погледнеш кода на модула inspect.
Т.е. задачата ще се проверява за именованите параметри само с функции, които имат __code__. Супер :) Благодаря за отговора.
Според мен Димитър имаше предвид да помислиш друго решение.
Опааа... мда... благодаря за бързата намеса :)