1. Python / Говнокод #21798

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    class ScanFiles:
        DIRECTORY_SEPARATOR = '/'
    
        def __init__(self, rootDir, searchPattern, filesExtension = None):
            self.rootCatalogPath = rootDir # Absolute path to directory to parse
            self.filesExtension = filesExtension # Specified files(if typed)
            self.pattern = searchPattern # Key word's regex pattern
    
        def scan(self, path = '', absPath = ''):
            if (not os.path.exists(self.rootCatalogPath)):
                raise Exception("Directory is not exists.")
    
            if (not absPath):
                absolutePath = self.rootCatalogPath + self.DIRECTORY_SEPARATOR + path
            else:
                absolutePath = absPath + path + self.DIRECTORY_SEPARATOR
            for item in os.listdir(absolutePath):
                if (os.path.isdir(absolutePath + item)):
                    # recursive call
                    self.scan(item, absolutePath)
                elif (os.path.isfile(absolutePath + item)):
                    if (self.filesExtension):
                        if (not re.search('\.%s$' % (self.filesExtension), item)):
                            return 0;
                    self.__parse_file(absolutePath + item)
    
        def __parse_file(self, pathToFile):
            f = open(pathToFile)
            if (re.search(self.pattern, f.read(), re.IGNORECASE)):
                print pathToFile;
            return 1;

    Человек осуществляет поиск подстроки в файлах указанной директории :D

    Запостил: ayylmao, 07 Декабря 2016

    Комментарии (79) RSS

    • ЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫЫ, БЛЯ!
      Ответить
    • Там есть какое-то серьезное говно? Я из косяков вижу только мелочи: говноскобочки у if, бесполезные return'ы, и незнание os.path.join и os.walk.
      Ответить
      • os.walk изобрели же
        а так же модуль glob
        Ответить
        • Свелосипедил человек?
          Ответить
          • Особенно если єто скрипт для персонального пользования. Расскажите ему про grep -rn
            Ответить
          • Да тут все не канонiчно, какая то джава сплошная:
            Не пишет так питонец
            if (not os.path.exists(self.rootCatalogPath)):
                        raise Exception("Directory is not exists.")

            А пишет
            assert os.path.exists(self.rootCatalogPath), "Dir does not exist"


            Ну и сам подход показывает что человек не умеет модуль os и os.path
            А это стандартная либа, её бы подучить
            Ответить
            • Серьезно? Питонисты ассертят наличие файла? Хорошо, что я не питонист.
              Ответить
              • В обычном случае не ассертят. Но уж если они собрались проверять контракт (как в этом случае) то лучше ассерить, чем городить if.

                В целом же у питона принято ничего не ассертить. Просто пишешь в документации: "не суй сюда несуществующий файл" и все.
                Ответить
                • Ну а вообще, отбросив тот факт, что код по сути велосипед, и не самый качественный, все же как он написан, учитывая то, что человек этот(знакомец один мой) ~1 месяц(а то и меньше) как увлекся питоном? И да, раньше он активно читал по Java, чем и обуславливается стиль кода.
                  Ответить
                  • >>знакомец один мой
                    "у моей подруги с её парнем" (С) ;)

                    Ну если мы закрываем глаза на велосипеды, на незнание os и os.path, на громоздкость по сравнению с питонячьей идеологией, лишние скобки и на комменты вместо докстрок то в целом нормально.
                    Ответить
              • Я тут подумал кстати: ваще гря ассертить файл это трешпиздец.

                Отсутствие файла это НЕ ошибка программиста (если только у тебя не транзакционная fs как ntfs, когда ты можешь сначала проверить файл, а потом гарантировать что он никуда не делся).

                Нужно или вертать ошибку, или уж кидать FileNotFoundException, чтобы его ловили и проверяли снова.

                Но в 99% случаев можно считать что файл никуда не денется, а значит если программист не удосужился его проверить то можно и кинуть assert.
                Опять таки: если очень хочется fast fail
                Ответить
            • Ты обосрался, assert не работает
              Ответить
              • схуя?
                Ответить
                • Проверь?
                  Ответить
                  • Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 27 2016, 15:19:22) [MSC v.1500 32 bit (
                    Intel)] on win32
                    Type "help", "copyright", "credits" or "license" for more information.
                    >>> import os.path
                    >>> assert os.path.exists("/lol"), "sema durak"
                    Traceback (most recent call last):
                      File "<stdin>", line 1, in <module>
                    AssertionError: sema durak


                    проверил тебе, проверь
                    Ответить
                    • >py -O assert.py
                      Ответить
                      • Да, внезапно ассерты для того и нужны чтобы отключать проверки ненужного кода в продакшене, и оставлять их в тестах и тест сборках
                        В жабе тоже такое есть

                        А в сишечке есть препроцессор чтобы делать собрку для дебага.
                        Ответить
                        • Отож, так что тут не подходит. А зачем тогда ассерт вообще нужен как не для проверки аргументов/условий?
                          Ответить
                          • алгоритм, примерно, таков:

                            1) ты запускаешь код с ассертами. Он тормозит, потому что проверяет каждый пук, зато отлавливает тебе всё говно
                            2) ты отключаешь assert, и запускаешь продукт в продакшен, потому что он уже отлажен

                            Ну это как дебаговые сборки нативного кода: без оптимиизации и с символами и без base pointer omition итд
                            Ответить
                            • >Он тормозит, потому что проверяет каждый пук, зато отлавливает тебе всё говно
                              Не могли бы вы перевести это на человеческий язык?

                              >без оптимиизации
                              Что эти оптимизации дают для фитона?
                              >с символами и без base pointer omition итд
                              Для фитона ненужны
                              Ответить
                              • >>Не могли бы вы перевести это на человеческий язык?
                                Почитай книжку Code Complete, там масса примеров.

                                Очевидно что код, в котором проверяется контракт и постусловия более склонен к fast fail, и потому его легче тестировать. С другой стороны это может вызвать тормоза.
                                Например ты можешь после каждого вывоза метода обсчитывать состояние объекта и убеждаться что он консистентен. Это удобно делать через assert.
                                В продакшене ты просто скажешь -O, и уберешь ненужные тебе проверки.
                                Ответить
                            • 1) ты запускаешь код с ассертами. Он тормозит, потому что проверяет каждый файл, зато отлавливает тебе всё говно
                              2) ты отключаешь assert, и запускаешь продукт в продакшен, потому что уж там то все файлы всегда существуют, это же продакшн

                              ну-ну.
                              Ответить
                              • 3) оказывается что половина кода завязана на ассерты и без них не работает.

                                Я это понимаю. Ну ничто же не мешает мне верить в сказку
                                Ответить
                                • Ну как бы совет использовать ассерт для проверки наличия файла ведёт явно не в сказку.
                                  Ответить
                                  • охблядь)
                                    Совет был в том, чтобы не писать явно if и raise Exception. Проверка файла тут просто пример проверки контракта. Вопрос о том можно-ли считать наличие файла контрактом остается открытым.

                                    В любом случае код
                                    if (contract_is_broken()):
                                        raise Exception("psdts")

                                    ВСЕГДА хуже чем
                                    assert contract_is_broken(), "psdts"
                                    Ответить
                                    • А в питоне assert чем-то отличается от raise AssertionError?
                                      Ответить
                                      • ну только тем что выпиливается при -O
                                        Ответить
                                        • > выпиливается при -O
                                          А нахуя? Даже в сишке ассёрты и оптимизация - ортогональные вещи.
                                          Ответить
                                          • https://wiki.python.org/moin/UsingAssertionsEffectively

                                            . So if code uses assertions heavily, but is performance-critical, then there is a system for turning them off in release builds

                                            Тоже самое есть в жабе: ключ -ea.

                                            А потом пришли дурачки, и написали
                                            assert removeUser(user): "Failed to remove user";

                                            И оказалось что продакшен версии юзери не удаляются
                                            Ответить
                                    • > ВСЕГДА хуже
                                      Почему?
                                      Если банковская питушня, пусть лучше упадёт, чем в оптимизированном варианте заплатит кому-нибудь за товар None.
                                      Ответить
                                      • В оттестированном коде не должно быть уплаты None.
                                        А если мы не уверены в коде, то почему мы не проверяем каждую переменную?
                                        Ответить
                                        • В оттестированном коде может не оказаться файла который мы обрабатываем. И его то наличие мы и проверяем. Таким образом, raise в этом случае лучше чем assert.
                                          Ответить
                                        • В оттестированном коде не должно быть багов. Да, знаем.
                                          Но это наверно только в том коде, где программистам платят миллионы за час, а за малейший баг расстреливают. Или в том коде, корректность которого математически доказана, а доказательство проверено математиками, которых за каждый баг расстреливают.

                                          Если мы пишем важный код, связанный с оплатой реальными деньгами, мы не уверены в нём. И вот в той части, где надо платить, расставляем такие проверки, чтоб точно ничего не вышло, а в каком-нибудь гуе или шупоподавлялке для фотографий - assertы. Я это как-то так представляю на уровне идей.
                                          Ответить
                                        • > В оттестированном коде не должно быть
                                          Тесты могут доказать только то, что в коде есть баги. Обратного они не могут, увы.
                                          Ответить
                                          • Не факт, не факт... Сами тесты могут содержать баги, так что даже это они, строго говоря, не доказывают.
                                            Даже хардкорная формальная верификация ничего не доказывает, вдруг в прувере баги. Ну и предпосылки и модели, соответствие которым проверюется, всегда противоречивые или неполные.
                                            Человеческая природа несовершенна, надо с этим смириться.
                                            Ответить
                                            • Тест для теста - заведомо забагованная реализация.
                                              Ответить
                                              • >>>"заведомо забагованная реализация"

                                                Вспомнился твой анус.
                                                Ответить
            • Питонец пишет через EAFP (try/except там, все дела), а это залупка.
              Ответить
      • Знаю человека этого, он на Python только где-то месяц назад писать начал.
        Ответить
    • 1. Файлы не закрываются, легко может выжрать все дескрипторы и навернуться при поиске с корня.
      2. Если у пользователя нет прав на открытие всего одного файла в дереве, весь поиск накроется, когда до него дойдет.

      Если это отдельная утилита, её лучше выкинуть и заменить на grep -R / find + grep / ack / ag
      Ответить
      • 1. возможно это именно то, чего хотел автор
        2. вот да) слона-то никто и не приметил кроме тебя. PyCharm даже ругает за open() без with
        Ответить
      • Точняк. Действительно говно. Хотя в сипутоне будет само закрываться наверное при выходе из __parse_file.
        Ответить
        • почему??

          Imho ничо не будет само зкрываться, иначе как дескриптор вернуть?
          Контекст менеджер нужен
          with open('porno.jpg', 'r') as f:
              read_data = f.read()
          # тут он уже закрыт
          Ответить
        • > Хотя в сипутоне будет само закрываться наверное при выходе из __parse_file

          Не закроет, нужен with.
          Ответить
          • Я заморочился и поискал пруфы.

            https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_dealloc
            > The destructor function is called by the Py_DECREF() and Py_XDECREF() macros when the new reference count is zero.

            Для файлов это file_dealloc:
            https://hg.python.org/cpython/file/c6880edaf6f3/Objects/fileobject.c#l2400

            И оно закрывет файл:
            https://hg.python.org/cpython/file/c6880edaf6f3/Objects/fileobject.c#l618

            Ну и эксперементально подтверждается.
            Ответить
            • > The destructor function is called by the Py_DECREF() and Py_XDECREF() macros when the new reference count is zero.

              Py_DECREF() and Py_XDECREF() -- это куски сишного апи, к коду в топике не имеют никакого отношения. Когда-то в питоне мусор собирался счётчиком ссылок, но так циклы не удаляется. Сейчас там настоящий сборщик мусора, а
              Py_DECREF() и Py_XDECREF() нужны для сишных расширений.

              http://www.digi.com/wiki/developer/index.php/Python_Garbage_Collection
              Ответить
              • > Сейчас там настоящий сборщик мусора

                Хз, я вторым пользуюсь, там счетчик ссылок. И он обнуляется при выходе из __parse_file в данном конкретном коде из топика. Если ты говорил за какой-то новый петон, в котором нет подсчета ссылок, то ок.
                Ответить
              • Дело может быть и не в рефкаунте, а в том что питон понимает что к этому дескриптору больше не обратиться, и вхуячивает туда close() (или вообще создает объект на стеке и при выходе вызывается деструктор)

                Кроме шуток: запусти такую хуйню под strace:
                from time import sleep
                
                
                def some(pathToFile):
                    f = open(pathToFile)
                    return f.read()
                
                
                some("~/foo")
                sleep(5) # к этому моменту он ужэе будет закрыт


                А потом попробуй
                from time import sleep
                
                
                def some(pathToFile):
                    f = open(pathToFile)
                    f.read()
                    return f
                
                
                f = some("~/foo")
                sleep(5) # а вот к этому он еще НЕ будет закрыт
                f.read()
                Ответить
                • > Дело может быть и не в рефкаунте

                  Да похоже, что именно в нём. Выяснилось, что сейчас в обоих пистонах и счётчик ссылок, и гц одновременно. При этом всё это неявно и спрятано под капотом.
                  import dis
                  
                  def func(path):
                    f = open(path)
                  
                  dis.dis(func)

                  Выводит следующее:
                  5           0 LOAD_GLOBAL              0 (open)
                                3 LOAD_FAST                0 (path)
                                6 CALL_FUNCTION            1
                                9 STORE_FAST               1 (f)
                               12 LOAD_CONST               0 (None)
                               15 RETURN_VALUE
                  Ничего интересного в байткоде нет, счётчики ссылок изменяются где-то в кишках интерпретатора. Что ж, ГК познавательный.
                  Ответить
                  • В очередной раз убеждаюсь что GC нинужен
                    Ответить
                  • Полирну твои новые познания тем фактом, что в pypy счетчика ссылок нет, там когда гц проснется, тогда мусор и собирается.
                    Ответить
                  • И еще все питонячии объекты в интерпритаторе представлены структурой PyObject. Конкретно файлы - PyFileObject. Никакого отдельного сишного апи у сипитона нет. Так что ты зря говоришь, что между моими ссылками и питонячим кодом связи нет. Связь там прямая.
                    Ответить
                    • > Никакого отдельного сишного апи у сипитона нет.

                      А #include <Python.h> это что?

                      Я имел в виду, что всякие Py_DECREF нужны только когда пишешь модули на сишке и работаешь с пистоньими объектами. То, что интерпретатор их тоже в кишках использует — это логично, т.к. на одни и те же объекты могут ссылаться одновременно и сишный модуль, и интерпретатор. Просто не совсем очевидно.

                      > Связь там прямая

                      Да, это я уже понял.
                      Ответить
              • Настоящий это какой? Копирующий как в жаве?
                Ответить
                • Трейсящий, я думаю, который умеет разруливать циклы. И наверное ты имел в виду перемещающий, а не копирующий. Врятли в сипетоне перемещающий. Он же обычной сишной кучей пользуется для размещения объектов.
                  Ответить
                  • Почему перемещающий? Есть операция перемещения памяти, а не копирования?

                    Как трейсящий по-русски называется?
                    Ответить
                    • Перемещающий, потому что перемещает объекты по куче.

                      > Есть операция перемещения памяти, а не копирования?
                      Ну да, вынимаешь планку из одной материнки и втыкаешь в другую. Только это имеет такое же отношение к алгоритмам сборки мусора, как и твоя операция копирования.

                      > Как трейсящий по-русски называется?
                      Хз. Зачем тебе по-русски? Гугли tracing gc.
                      Ответить
                      • >Перемещающий, потому что перемещает объекты по куче.
                        Он копирует, а потом старое место высвобождает :)

                        > Зачем тебе по-русски?
                        Ну эти вещи не настолько элементарные чтобы понимать их на бусурманском.
                        Ответить
                        • Похоже я ошибся. Похоже действительно этот алгоритм называется копирующим сборщиком мусора. А перемещающий/неперемещающий - это типа классификация.
                          Ну суть от этого не меняется.
                          Ответить
                          • Ух ты, первый раз кто-то на говнокоде признал свою неправоту :)
                            Ответить
                        • Судя по этой ссылке https://www.quora.com/How-does-garbage-collection-in-Python-work
                          в сипитоне вариация на тему mark & sweep с поколениями.

                          И там явно отмечено, что он не копирующий:
                          > Some garbage collectors deal with fragmentation by copying all live objects into a different section of memory and freeing up an entire section of memory, but CPython doesn’t.
                          Ответить
                          • А вот интересно мне стало: почему джависты и дотнетчики обычно учат как работает их GC, довольно хорошо представляют себе всякие кишки (поколения, major/minor итд) и даже знают чем различные алгоритмы отличаются.

                            А питонистам (даже сеньёрам) подчас похуй совершенно. И в официальной доке про это мало.
                            Ответить
                            • Наверное потому что в петоне всем похуй на перфоманс, а на джаве хадупы всякие пишут.
                              Ответить
                            • Потому что жава жрет память, а в питоне жрет сишкоговно? Потому, что жава - это жырный ынтырпрайз, а код напитоне не имеют ту сложнотсь чтобы жрать память?
                              Ответить
            • Неприятно это признавать, но ты действительно прав.
              На винде IRP_MJ_CLEANUP летит пере выходом из функции. Во что референс каунтинг животворящий делает.
              На линуксе (судя по strace) тоже close() случается

              Тем не менее, это стандарт это нарушает, и гарантии нет.
              Ответить
              • Че это тебе неприятно? Ректальный батхерт ануса?
                Ответить
              • >и гарантии нет.
                зис. Как например никто не гарантирует что str += производится на месте. В сипитоне-то да, а в остальных может быть и нет. Впрочем, всем похуй.
                Ответить
                • Как например никто не гарантирует что твоя мать даст в зад за 300 рублей на месте. В рот-то да, а в остальные отверстия может быть и нет. Впрочем, всем похуй.
                  Ответить

    Добавить комментарий