Змея / Говнокод #21798 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 ayylmao, (Updated )

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

  • Там есть какое-то серьезное говно? Я из косяков вижу только мелочи: говноскобочки у if, бесполезные return'ы, и незнание os.path.join и os.walk.
    Ответить
        • Особенно если єто скрипт для персонального пользования. Расскажите ему про 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
              Ответить
                • 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


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

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

                          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
                                        А нахуя? Даже в сишке ассёрты и оптимизация - ортогональные вещи.
                                        Ответить
                                        • 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
                Ничего интересного в байткоде нет, счётчики ссылок изменяются где-то в кишках интерпретатора. Что ж, ГК познавательный.
                Ответить
                • Полирну твои новые познания тем фактом, что в 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 рублей на месте. В рот-то да, а в остальные отверстия может быть и нет. Впрочем, всем похуй.
                Ответить

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

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8