нещо не мога да разбера идеята...може ли някой да ми разясни...
Help за curry :)
-
24.03.2009
-
Присъединявам се :)) Нали тия две звездички, са свързани със речник, а в примерчетата няма такова нещо. Нещо ми е много шантаво. И думи като частичното прилагане ме плашат :)
25.03.2009 (променeно 25.03.2009) -
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)
25.03.2009 (променeно 25.03.2009) -
Забавни снимки.
редактирано
този пример ме притеснява също, може ли да имама повече от един *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
в примерния тест.Също така това би ви било адски безполезно.
25.03.2009 (променeно 25.03.2009) -
А забраната за import е, за да не използваме inspect?
25.03.2009 -
Например.
25.03.2009 -
А освен inspect, какви други начини има да определим колко аргумента взима функция, как help() определя с колко аргумента е дадена функция? Питам по принцип, не се отнася за тази задача.
25.03.2009 -
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')
25.03.2009 (променeно 25.03.2009) -
>>> 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 за спама).
29.03.2009 (променeно 29.03.2009) -
В случая с curry инспекция не ти е необходима. Иначе може да погледнеш кода на модула inspect.
29.03.2009 -
Т.е. задачата ще се проверява за именованите параметри само с функции, които имат __code__. Супер :) Благодаря за отговора.
29.03.2009 -
Според мен Димитър имаше предвид да помислиш друго решение.
29.03.2009 -
Опааа... мда... благодаря за бързата намеса :)
29.03.2009 -