@Tishka17
Tishka17
16 Sep 2016

А как мне динамически создать функцию с определенными аргументами?
Сейчас у меня f(args, *kwargs), но о ней непонятный хелп и наличие обязательных параметров приходится руками делать.
У меня генерится куча таких функций с разными параметрами.

Рекомендовано: partizan
16 Sep 2016

Tishka17, определёнными? так ты не юзай звезданутые аргументы

16 Sep 2016

def func(позиционный_аргумент1, позиционный_аргумент2, ключевой_аргумент1=значение, ключевой_аргумент2=значение)

#oojyuh/2 в ответ на /1
16 Sep 2016

Так я в динамике их должен задать

#oojyuh/3 в ответ на /1
16 Sep 2016

Tishka17, я не догнал что ты хочешь сделать, можешь пример дать?

#oojyuh/4 в ответ на /3
16 Sep 2016

SetazeR, грубо: из файла у меня грузится список параметров. Есть реальная функция, работающая с *args. Я хочу иметь именованную функцию уже с конкретными параметрами.

#oojyuh/5 в ответ на /2
16 Sep 2016

SetazeR, то есть есть функция f(*args) и есть генератор функций. Вот я хочу вызвать gen("name", "arg1") и чтобы она вернула функцию как будто она name(arg1), но по сути работающую как f

#oojyuh/7 в ответ на /4
16 Sep 2016

питон - не функциональный язык

#oojyuh/8 в ответ на /7
16 Sep 2016

Tishka17, какое забористое и сильное колдунство.

#oojyuh/9 в ответ на /7
16 Sep 2016

в нормальных языках это обычные практики

#oojyuh/10 в ответ на /9
16 Sep 2016

в питоне лямбды неполноценные

#oojyuh/12 в ответ на /11
16 Sep 2016

a13, ¯_(ツ)_/¯
Я с таким колдунством ещё не сталкивался. Хотелось бы посмотреть на практическую реализацию.

#oojyuh/13 в ответ на /12
16 Sep 2016

a13, щас я тупо юзаю *args и **kwargs и в __doc__ пишу что надо. Но приходится руками состав проверять

Комментарий был отредактирован в 12:04:22 16.09.2016
#oojyuh/14 в ответ на /10
16 Sep 2016

из рабочего кода(вроде бы ничего nda-ного тут нет):

(define trs-values
  (compose values* (curryr map (list str-tr identity))))

(define-values (string-conv-gen-tr string-conv-gen)
  (trs-values
   (lambda (tr)
     (lambda (re-fmt)
       (lambda (s)
         (pregexp
          (format (string-append "(?i:" re-fmt ")")
                  (tr s))))))))
#oojyuh/15 в ответ на /13
16 Sep 2016

хорошо работает, в ынтырпрайзных продакшнах

#oojyuh/18 в ответ на /17
16 Sep 2016

a13, в смысле каким образом это работает? что тут происходит?

#oojyuh/19 в ответ на /18
16 Sep 2016

генерятся функции-генераторы генераторов функций для строки без изменений (indentity) и с транслитерацией (str-tr)
внутре просто матчинг регулярного выражения (pregexp)

#oojyuh/20 в ответ на /19
16 Sep 2016

Так оно может сгенерировать функцию с двумя аргументами или с тремя в зависимости от аргументов?

#oojyuh/22 в ответ на /20
16 Sep 2016

сопсна, первая функция просто делает враппер для того, чтобы одним махом использовать её и для обычной сторки и для измененнной
второе определение декларирует функции string-conv-gen-tr
string-conv-gen таким образом

     (lambda (re-fmt)
       (lambda (s)
         (pregexp
          (format (string-append "(?i:" re-fmt ")")
                  (tr s)))))

где tr - функция трансляции строки

re-fmt - регулярка, которая, в общем случае определяет, в каком месте
нужно матчить оттранслированную строку s (начало, конец, середина,
пофиг)

регулярка задаётся при генерации, окончательной функции, которая имеет
вид

       (lambda (s)
         (pregexp
          (format (string-append "(?i:" re-fmt ")")
                  (tr s))))

ну т.е. просто задаётся строка, транслируется и матчится.

Смысл колдунства (хотя какое колдунство, обычная функциональная
практика, как уже сказал) - одним махом нагенерить 8 (или даже больше,
ща уже не помню) функций однотипного вида. Меньше копипасты - меньше
потенциальных ошибок.

#oojyuh/25 в ответ на /19
16 Sep 2016

конкретно это - нет, я тут просто показал человеку, зачем нужно вообще генерировать функции, а так - наздоровье (правда тут уже придётся макросами, а не функциями. если в scheme, конечно)

Комментарий был отредактирован в 12:29:28 16.09.2016
#oojyuh/28 в ответ на /22
16 Sep 2016

Вот это похоже на нужное, но не осилил

#oojyuh/32 в ответ на /26
16 Sep 2016

норм такое колдунство.

#oojyuh/34 в ответ на /29
16 Sep 2016

Nico-izo, неплохо. А я в прошлый раз подумал, что раз CodeType требует codestring, то проще сразу eval-ом сделать, все равно процесс один и тот же.

#oojyuh/35 в ответ на /29
16 Sep 2016

Сделать, чтобы хелп выдавал нужное, получилось. И даже дефолтное значения вроде съел из массива. Но при вызове такой функции интерпретатор просто закрывается

#oojyuh/36 в ответ на /33
17 Sep 2016

Количество параметров - это argcount? Или еще что-то надо менять?

#oojyuh/38 в ответ на /37
20 Sep 2016

partizan, ЧЯДНТ?

def f(*args):
    print args

def f2(args):
    print "f2:", args
    return f(args)


y_args = ["x","y","z"]
co = f2.__code__
new_co = CodeType(
    len(y_args),
    co.co_nlocals,
    co.co_stacksize,
    co.co_flags,
    co.co_code,
    co.co_consts,
    co.co_names,
    tuple(y_args),
    co.co_filename,
    "f",
    co.co_firstlineno,
    co.co_lnotab)
new_y = FunctionType(new_co, globals())
new_y.func_defaults=tuple([None]*(len(y_args)))

new_y(1,2) #работает
new_y(z=1, y=2, x=3) #не работает - TypeError: f() got multiple values for keyword argument 'z'
#oojyuh/39 в ответ на /37
20 Sep 2016

надо было на перле, да? // я надолго запомню этот кодогенератор в dbtools.

#oojyuh/42 в ответ на /41
20 Sep 2016

Очевидно, что на плюсцах. // DBTools, конечно, говно, потому что всё вообще говно, но на самом деле не такое страшное.

#oojyuh/44 в ответ на /42
20 Sep 2016

плюсцы же тоже говно

#oojyuh/45 в ответ на /44
20 Sep 2016

Менее говно, чем петушон. Даже явка менее говно, чем петушон, хотя и большее говно, чем perl.

#oojyuh/46 в ответ на /45

Добавить пост

Вы можете выбрать до 10 файлов общим размером не более 10 МБ.
Для форматирования текста используется Markdown.