- 1
- 2
- 3
- 4
- 5
def f(x):
return x.strip()
lines = map(f, open("1.txt", "r"))
open("1.txt", "w").write(" ".join(lines))
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−105
def f(x):
return x.strip()
lines = map(f, open("1.txt", "r"))
open("1.txt", "w").write(" ".join(lines))
ХАСКЕЛЕПРОБЛЕМЫ™. Теперь и в питоне.
Исходный файл содержит 3 строчки:
just
as
planned
Питон 2.7:$ python2.7 1.py
$ cat 1.txt
just as planned
Питон 3.0:$ python3.2 1.py
$ cat 1.txt
Можно и без дополнительных функций.
Большое спасибо, не знал такой фишки.
Но хаскелепроблема то не в этом ;)
Но вот на случаях, когда первый генератор имеет побочный эффект теперь получается вот такой вот фейл. В данном случае питон успел потереть файл вторым open'ом задолго до того, как прочитал из него первую строку.
Да не совсем как бы ОК... скрипт работал-работал, попробовал портануть под python3 - начал херить файлы. Все-таки в питоне3 полно несовместимостей с двойкой.
> Это к тому же шеллопроблемы
Да я в курсе, еще когда с линуксом только-только начинал знакомиться нарвался на эту траблу, только вместо grep'а был sed... Кстати если обобщить - это проблема любых ленивых конвейеров.
А мне кажется, что это очень и очень годно. Даже несмотря на кучу похеренного софта. Даже несмотря на необходимость выучить принципиально новый язык.
Это того стоит.
А в вашем мире тестов не придумали?
Признайтесь, вы всегда пишете тесты для не mission-critical утилит в 20 строчек?
не правда. к шелу данная проблема относится очень слабо.
шел интерпретирует сроку комманды в один проход, в следующий проход открывает файлы, в следущий проход запускает комманды. поэтому cat всегда будет видеть пустой файл. ничего не lazy, все очень детерминистично.
да и каждый админ знает что "> filename" в шелле есть самый быстрый способ обнулить файл.
"когда первый генератор имеет побочный эффект теперь получается вот такой вот фейл."
ацтой.....
теперь я понимаю почему после путхона 3го, народ начал еще более активно форкать 2ую версию.
Всем давно известно, что ленивая обработка данных весьма хреново сочетается с побочными эффектами. Я за то, чтобы map был ленивым. Хочется неленивой обработки - есть for и list comprehensions.
Третий Python устранил много фейлов второго, и когда-нибудь его вытеснит. Бубунта последняя вроде на тройку окончательно перешла.
Но нет неленивого map'а.
> Третий Python устранил много фейлов второго [...]
Но как я вижу - так же добавил новых.
Как я на эту тему не думаю, все равно не могу себе представить жизнь на "there is only one true way to do this" языках.
Ну можно вот так делать, если ленивость мешает: Ленивость в мапе то фишка то хорошая, годная. Просто за что не люблю питон - 3.0 и 2.0 не совместимы чуть более чем полностью.
Отношение Гвидо к разрабам: "Мы пилим новый убер-язык, идите нахуй со своими наработками".
Прекрасно. К тому же, на деле всегда there is more than one way (особенно, когда дело уходит дальше hello world), но есть среди них есть самый краткий, читабельный, понятный и идиоматичный.
Или join теперь использует yield?
Мне кажется, str.strip выглядит понятнее
Но на самом деле добиться полного соответствия изначальному коду не удасться, т.е. если бы у нас был еще какой-нибудь Foo.strip, то ничего бы не получилось.
Чорд, не дочитал.
В моем говнокоде с отдельной функцией работает duck-typing, и мапать можно как обычные строки, так и юникодные, так и вообще все что угодно, лишь бы у него был strip().
В вашем же случае всегда вызывается метод класса str, с вот такими последствиями: TypeError: descriptor 'strip' requires a 'str' object but received a 'unicode'. Хотя в данном конкретном случае все будет работать.
А насчет в любом случае не согласен. С большими двоичными файлами часто такое не прокатит по соображениям производительности и места на диске.
прокатит по соображениям производительности
и места на диске
а вы представьте, что надо зашифровать/дешифровать/упаковать/распаковать файл, или любую другую трансформацию. и в процессе ее оказывается, что входящий блок меньше исходящего... а файл, по определению, не резиновый, и исходящий блок просто потрет следующий входящий - эпикфейл.
так что местом на диске придется запастись... что касается производительности, то операция переименования/перемещения файла весьма дешева (в сравнении, скажем, с самой трансформацией, или тупо копирования).
поэтому архиватором @bormandа пользоваться не буду o_O
> а вы представьте, что надо зашифровать/дешифровать/упаковать/распаковать файл, или любую другую трансформацию
> поэтому архиватором @bormandа пользоваться не буду o_O
А я и не предлагаю такую методику для подобных трансформаций ;)
А сам юзал запись в тот же файл без транзакции через переименование т.к. файл все равно временный, даже если он похерится или запишется не до конца - хрен бы с ним, в следующий раз заново сгенерится. А лишнюю строчку с переименованием писать было влом.
я не буду рад проге, которая ни результат не сделает, да еще и мои файлы похерит. а все потому, что автор поленился написать одну строчку.
Да я на самом деле не меньший параноик, но в данном случае (костыль, допиливающий пару строк в мейкфайле сразу после его генерации) проблем не вижу. Да и в старом питоне сфейлиться он мог только если место на диске кончилось, или при краше во время записи, что довольно маловероятно, и исправляется перегенерацией.
кончилось, или при краше во время записи
или так сложились звезды. иногда вылетит Error - не поймаешь фейлится там, и по такой причине, откуда совсем не ждешь
к тому же, если это небольшой мейк, то можно его сначала полностью считать в память.
Теперь по поводу перехода на третий питон. Радуйтесь своему спиду. Хотели суперпупер динамический язык, где в принципе нельзя даже переменную обьявить (аналог use strict)? Где к переменной можно обратиться как к var или как к "var"? Получите, а теперь резво радуйтесь, что статический анализ и рефакторинг не работают вообще никак и писать на этом уебище без тестов вообще нельзя, т.к. отвалиться может вообще все, что угодно и выяснится это только в момент выполнения того участка кода.
Я всё больше убеждаюсь, что без тестов нельзя писать вообще ни на чём.
Ну а кто пишет бинарную (де)сериализацию без тестов, тот ССЗБ.