[о боже какой говнокод] Вопрос знатокам ФЯ и/или питона [решена]
Вопрос второй: Как это менее говнокодно выразить в питоне?rtfm
Вопрос первый: как то, что я хочу, называется в теории ФЯ?наверное вот это http://en.wikipedia.org/wiki/Currying
partial знаю, но что-то не допер, как это сделать так же удобно для пользователя: чтобы он просто вызывал функцию с нужными ему параметрами и передавал результат в фрэймворк. Хотя может быть есть идея, надо будет еще подумать.
def decor(func):
return lambda *args: partial(func, *args)
@decor
def regex_extractor(regex, f):
Вот такой декор позволяет отрезать любое количество параметров с начала. Это более лакончино, но я теперь не могу сказать, что в какой-то отдельный момент времени понимаю все детали работы этого дела
хотя не, вот сейчас понимаю
вот, спасибо, так гораздо больше по делу ищется, binding — не то, конечно.
В C++ — std::bind.
file = open(...)
f = lambda x : regex_extractor(file, x)
...
f('some text')
Я хочу один параметр задать в одном месте, а другой задавать позже.Поправь, что ли, "один" на "первый", так?
ну я же объяснил, файл открывается уже внутри, на момент создания функции мне этот параметр неизвестен. Да, можно каждый раз писать лямбду, когда я хочу создать новый экземпляр, но мне как-то лень. По сути у меня и вызывается каждый раз лямбда, просто я это не пишу.
Вернее, для второго аргумента это сечение flip f.
flip :: (a -> b -> c) -> (b -> a -> c)
flip f x y = f y x
Вернееневерно, сечение это лишь синтаксический сахар для построения замыканий для операторов
http://www.haskell.org/haskellwiki/Section_of_an_infix_opera...
то, что ты описываешь лучше назвать "частичное применение", которое актуально как раз для каррированных функций
неверно, сечение это лишь синтаксический сахар для построения замыканий для операторовОбъясни мне разницу, а?
http://www.haskell.org/haskellwiki/Section_of_an_infix_opera...
то, что ты описываешь лучше назвать "частичное применение", которое актуально как раз для каррированных функций
Утром вечером удренеет ©
def regex_extractor(regex):
def wrap(f):
if isinstance(regex, basestring):
regex = re.compile(regex)
f.seek(0)
for line in f:
match = regex.search(line)
if match:
return " ".join(match.groups
else:
return "<NF>"
return wrap
казалось бы, почему не засунуть эти функции и файл в класс, инстанциировать объект с нужным файлом, и вызывать методы без лишних аргументов, общаясь в них с self.file?
И еще раз, я пишу либу. Юзеры ее вызывает в духе collect_data([regex_extractor("Time: (\d+) seconds" something_else_extractor("Hello, wordl", 42)]). Т.е. collect_data принимает список функций с одним параметром-файловым объектом (и потом уже внутри либы они прогоняются для набора файлов). Да, можно передать callable-объект, но это буэшечка же вроде.
Юзеры ее вызывает в духе collect_data([regex_extractor("Time: (\d+) seconds" something_else_extractor("Hello, wordl", 42)]). Т.е. collect_data принимает список функций с одним параметром-файловым объектом (и потом уже внутри либы они прогоняются для набора файлов).в твоем вызове collect_data принимает список значений, возвращаемых функциями.
Почему ты предпочел такой интерфейс, казалось бы более естественному:
obj = myClass(file)
obj.regex_extractor("Time: (\d+) seconds") # save extracted data in object
obj.something_else_extractor("Hello, wordl", 42) # save extracted data in object
obj.collect_data #process saved data?
собственно я че докапываюсь: мне кажется неявное участие во всех этих вызовах где-то когда-то открытого файла это как раз то, с чем пытается бороться функциональное программирование. При этом в чисто объектной модели все как-то более прозрачно - объект однозначно связан с файлом и ты вызываешь нужные методы обработки, понимая для каких данных ты их вызываешь.
мне кажется неявное участие во всех этих вызовах где-то когда-то открытого файла это как раз то, с чем пытается бороться функциональное программированиеС каких пор partial application в функциональном программировании под запретом?
def collect_data(funcs):
for filename in filenames:
with open(filename) as f:
print " ".join(func(f) for func in funcs)
и вообще
obj = myClass(file)я же написал даже с примерами, что файлов несколько и какой именно файл юзеру не известно, он просто задает действия, которые с ними надо выполнить.
obj = myClass(file)Ну тут скажем, можно инстанцировать фабричным методом.
я же написал даже с примерами, что файлов несколько и какой именно файл юзеру не известно, он просто задает действия, которые с ними надо выполнить.
obj = my_framework.give_me_my_regexp_extractor
...
Но в целом это не по змеячи.
Где то читал статью недавно, про некую либу на python, которую делала какая то контора и в которой были тыщи строк кода и сотни классов.
Чуваку, который это использовал, надоело что всё ломается и глючит с каждой новой версией либы, он стал пинать чуваков из конторы и они совместными усилиями избавились от классов вообще и осталось чё то типа полсотни строк кода ...
Посыл такой, что подход, предложенный форумчанином с ником из цифр в конце концов приведёт к "тысячам строк кода и сотням классов".
collect_data([regex_extractor("Time: (\d+) seconds" something_else_extractor("Hello, wordl", 42)])
def collect_data(funcs):
for filename in filenames:
with open(filename) as f:
print " ".join(func(f) for func in funcs)
Да, можно передать callable-объект, но это буэшечка же вроде.мне кажется, или кто-то путается в показаниях?
мне кажется неявное участие во всех этих вызовах где-то когда-то открытого файла это как раз то, с чем пытается бороться функциональное программирование."Хранящийся в функции" — это не "где-то когда-то открытый". Это вполне себе stateless. Состояние файлового объекта хранится явно, в передаваемом значении.
.
мне кажется, или кто-то путается в показаниях?Мне кажется, кто-то путается в нити обсуждения.
Я имел в виду класс с написанным вручную методом __call__.
Я имел в виду класс с написанным вручную методом __call__
Да, можно передать callable-объект, но это буэшечка же вроде.и кстати, почему это буэшечка?
Это вполне себе statelessВ референсной реализации топикстартера - еще как statefull, а благодаря декоратору догадаться об этом можно, разве что если вам удалось догадаться про "класс с написанным вручную методом __call__"
from functools import wraps
def regex_extractor(regex):
@wraps(regex_extractor)
def wrap(f):
# code goes here
pass
return wrap
def other_extractor(some, parameters):
@wraps(other_extractor)
def wrap(f):
# code goes here
pass
return wrap
def collect_data(funcs):
for filename in filenames:
with open(filename) as f:
print " ".join(func(f) for func in funcs)
collect_data([regex_extractor("foo (bar)" regex_extractor("(foo) bar" other_extractor("foo", "bar")])
Вполне питонно, зачем городить классы тут? И сколько бы пришлось накатать? И насколько это было бы понятно?
функторы — это что-то из плюсовых приемов.
да, что касается файла — решение не из лучших, его в идеале тоже надо переделать. Ну я могу легко переделать и передавать уже считанные строки файла, например, это отдельный вопрос.
В референсной реализации топикстартера - еще как statefulА, ну нечетал.
мне кажется, или кто-то путается в показаниях?Java-архтекторы набижали.
from functools import wrapsты это запускал ; )
def regex_extractor(regex):
@wraps(regex_exctractor)
def wrap(f):
# code goes here
pass
return wrap
regex_extractor("foo (bar)")
нет, конечно, видно же, что для демонстрации. Ну опечатался на буквочку, ну и что? Вон там вообще используеются filenames, которому ничего не присвоено. Короче тупой троллинг какой-то
Ну опечатался на буквочку
from functools import wraps
def regex_extractor(regex):
@wraps(regex_exctractor)
def wrap(f):
# code goes here
pass
return wrap
Короче тупой троллинг какой-томне интересно было понять почему ты выбрал такое решение. я не встречал такого в интерфейсах.
ЗЫ ну так и почему передавать callable - буэшечка?
def regex_extractor(regex):... чувак, пробелами меня на форуме еще не подъебывали Причем у меня все правильно в посте, я не знаю, как ты это копируешь.
def wrap(f):
# code goes here
pass
return wrap
ЗЫ ну так и почему передавать callable - буэшечка?передавать его окейно, но буэшечно в таком языке, как питон, с кложурами, создавать класс для решения моей задачи.
пробелами меня на форуме еще не подъебывалиблин, я тебя не пробелами подъебываю, а тем что там декоратор не нужен и не работает, зато смущает реально и я его зачеркнул.
вообще сознаюсь, я как-то пропустил мимо сознания твою утреннюю версию - она окейная.
С другой стороны я до сих пор не видел программных интерфейсов организованных таким образом. В твоем случае, если пользователь задумает дополнить твою либу еще каким экстрактором ему придется писать неочевидным образом устроенную функцию, которая принимает в качестве аргументов все кроме файла и возвращает функцию которая уже ест только файл.
Обычно в тех api что я видел в такой ситуации передается собственно функция которая ест все аргументы и с ней список (дополнительных) аргументов к ней.
Обычно в тех api что я видел в такой ситуации передается собственно функция которая ест все аргументы и с ней список (дополнительных) аргументов к ней.ну, кстати, да. Просто меня занял именно такой путь рассуждения, как в первом посте. Да, юзерам надо показывать пример. Ну да, можно параметры и отдельно.
[offtop] Мне кажется или питон набирает популярность на флокале? [/offtop]
Мне кажется или питон набирает популярность на флокале?Да хз. Я уже давно им пользуюсь, потому что писать скрипты на баше мне нравится меньше чем на питоне. Ну гуи рисовал по-быстрому на питоне+Qt. А серьёзно питоном пользуются только веб-программисты, где он всё же удобнее пыхпыха. Других областей применения питона в больших разработках я не встречал. А если пишут на нём по большей части скриптики, то что там обсуждать?
Разнообразные учёные очень любят использовать Питон ещё для всяких вычислений, и выбивают под его развитие огромные количества бабла, судя по продвинутости numpy, SciPy, Sage, IPython, Cython, и прочих взаимноопыляющих проектов. Хотя до России это новомодное веяние могло ещё не дойти!
я даже на симпи нафигачил программку полгода назад
Оставить комментарий
Serab
Идея: есть функция от скажем двух параметров. Я хочу один параметр задать в одном месте, а другой задавать позже.В моем конкретном случае это функция, которая как-то разбирает внутренности файла и вычленяет оттуда некоторую информацию. Пример: regex_exctactor ищет заданный регэксп. Есть и другие, но первым параметром у них всегда файловый объект. Так вот этот параметр файловый объект задается где-то внутри фрэймворка, а юзер по сути должен фрэймворку передать функцию от единственного параметра. Надеюсь, понятно.
Вопрос первый: как то, что я хочу, называется в теории ФЯ?
Нахуярил такой говнокод:
Вопрос второй: Как это менее говнокодно выразить в питоне?