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

    −52

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    def huj(param=''):
        pass
    
    def pizda(param=None):
        huj(param)

    Ломаю гет. Внимание, вопрос: как сделать, чтобы если в pizda пришел дефолтовый параметр, она передала дефолтовы параметр для huj (естественно, не зная его)? Все что мне пока пришло в голову - вручную формировать kwargs и удалить оттуда ненужные ключи.

    Запостил: 3_14dar, 31 Декабря 2015

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

    • def pizda(param=None):
          if param is None:
              huj()
          else:
              huj(param)

      Или нужен однострочник?
      Ответить
      • А если у тебя x парамтеров, сколько будет веток? x**n?
        Ответить
        • иногда может подойти такой вариант
          def pizda(param=None):
              huj(param or None)
          Ответить
          • перечитал вопрос, понял что сморозил хуйню.
            по сабжу может помочь модуль inspect
            import inspect
            def get_default_args(func):
                args, varargs, keywords, defaults = inspect.getargspec(func)
                return dict(zip(args[-len(defaults):], defaults))
                
            def huj(param=''):
                return param
            
            def pizda(param=None):
                if param == get_default_args(pizda)["param"]:
                    return huj(get_default_args(huj)["param"])
                else:
                    return huj(param)
                    
            assert pizda() == '', "huj tam"
            assert pizda('huj') == 'huj', "huj tam plaval"
            Ответить
    • http://stackoverflow.com/questions/29566400/avoiding-code-repetition-in-default-arguments-in-python/29570138
      Ответить
      • Ты не понел. Я не знаю, какой дефолтовый параметр в хуе. Как я могу его передать если я его не знаю (только без inspect, пжалста)
        Ответить
    • def pizda(param=None):
          kwargs = {'param': param} if param is not None else {}
          huj(**kwargs)

      вот единственное что мне пока в голову пришло
      Ответить
      • Ну вот жаль, что нету условного добавления в словарь, типа
        kwargs = { 'param' : param if param is not None }
        Ответить
        • тогда уж мечтай слаще
          kwargs = { 'param' : param IfExist}
          Ответить
          • Не универсально.
            Ответить
            • Ну универсальнее добавить пустой элемент для словаря

              kwargs = { 'param' : (param != None ? param: skipThis)  }
              Ответить
              • Ну самый простой вариант - не хранить в словаре значение None. А вместо исключения о ненайденном ключе возвращать None.

                В общем-то случаев, когда важно отличить None от отсутствия, на практике почти и нету.
                Ответить
                • и мотивировать ставить заглушки не безликим None а спешалкейсом конкретного типа
                  Ответить
                  • Да не нужны эти заглушки вообще в 99.9% случаев.
                    Ответить
                    • >> Да нинужоны эти заглушки вообще в 99.9% случаев.

                      fixed
                      Ответить
                      • Ну вот когда тебе последний раз на практике понадобилось отличать отсутствие элемента в хешмапе от значения null/None? И чем это было вызвано?

                        Имхо, и все эти "как отличить None от не переданного аргумента" тоже горе от ума.
                        Ответить
                        • Мне - ни разу. Но мало ли. Я вообще не особо опытен и почему я опять подумал о хентае с застенчивыми девочками?
                          Я просто к тому, что если это будет кому то нужно, но ему придется чутка (а в случае со студентами - очень сильно) шевельнуть мозгой - и это хорошо
                          Ответить
                        • А если с none исключение выкинет?
                          Ответить
                          • Я про вызов def foo(arg=None) с None и без аргумента. Случаев, когда реально надо отличить foo() от foo(None) ничтожно мало. И с хешмапой - аналогично, мало где надо отличать key not in map от map[key] is None.

                            Ты про какое исключение?
                            Ответить
                            • def foo(arg=0):
                                  arg +=1
                              Ответить
                              • А, я немного про другое говорил - что очень редко надо отличать None из дефолта от None из аргумента. Криво сформулировал, да, сорри.

                                Т.е. для твоей функции это будет 0 из дефолта и 0 из аргумента.
                                Ответить
                                • А я создавая тему спрашивал, как передать дефолтный аргумент, не зная его.
                                  Ответить
              • Такой себе none, но другой? Зачем в жаваскрипте два none?
                Ответить
                • > Зачем в жаваскрипте два none?
                  Возможно, чтобы отличать намеренную пустоту от естественной. Мало ли что в голову придёт, когда запиливаешь язык на скорость.

                  А вообще, как показывает практика, это недоразумение. Вот хотим мы передать пустоту - передаём void. Нормально. Хотим опциональную пустоту. Передали - void. Не передали - undefined. Отлично. А теперь хотим передать опциональный undefined, т.е. различать, передали ли мы undefined или ничего не передали. И вот тут оказывается, что нельзя. void - нормальное значение, undefined - неоднозначен. Логично предположить, что двух значений недостаточно. Требуется бесконечное количество пустых значений, чтобы можно было отличить значимую пустоту более низкого порядка от отсутствия значения.
                  Ответить
                  • Но можно положить, что этот undefined всегда означает "не передано". Не важно, каким способом он попал в функцию. Хоть руками, хоть от отсутствия аргумента. И тогда всё ок.
                    Ответить
                    • Это я и предположил - сделать второй none который будет игнорироваться или вырезаться из списка аргументов.
                      Ответить
                      • Но из этого вырастает странная хрень. Каждый понимает эти пустоты по-своему, проверяет хрен знает что и передаёт хрен знает что, проверяет намеренность хрен знает как и логичен по-своему.
                        Надо либо одно пустое значение, либо целый класс их, равный через ==, чтобы каждый в своей библиотеке мог определить свою пустоту, либо запретить передавать/сохранять undefined: не определено - undefined; передал undefined - передался null.
                        Ответить
                        • > Каждый понимает эти пустоты по-своему
                          Ну так ты, как разраб языка, скажи "вот эта пустота для таких-то целей, а вот эта - для таких-то".
                          Ответить
                          • Двачую, param=undefined воспринимать так, как будто param не передавали.
                            Ответить
                            • И наверное даже дефолты юзать, если передали undefined. Тогда и проблема из топика уйдёт.
                              Ответить
                              • >дефолты юзать, если передали undefined.
                                Это одно и то же.
                                Ответить
                              • Вот .val (или как там она называется) в jQuery - отличный пример. Передал случайно undefined - и не только сделалось то, чего не хотел, но и ещё и упала цепочка (причём следующий вызов как в сишечке, когда кто-то невинный упал, когда пошёл в порченую память) со странной ошибкой "Ололо у строки нет такого метода".
                                Ответить
                          • От этого только разврата больше будет, ведь не все послушают.
                            А в том же жс можно смотреть arguments.length, использовать in и т.д., т.е. хватило бы и одной пустоты.
                            Ответить
                            • Это будет обрабатываться языком, блин!
                              Ответить
                              • Ну, если будет, то хорошо. А не та жс-каша, что сейчас.
                                Ответить
                                • Ну да, мне пришла идея сделать это специальным undefined или на уровне языка, или через декораторы и ко.
                                  Ответить
        • > kwargs = { 'param' : param if param is not None }
          kwargs.update({} if param is None else {'param': param})
          Ответить
          • Ну это уже пост-фактум добавление. Тогда, имхо, проще и нагляднее будет:
            kwargs = {}
            if param is not None:
                kwargs['param'] = param
            Ответить
        • У них и сложения словарей нету в одну строчку.
          Ответить
          • Не запилишь ты для словарей сложение, оно неассоциативное получится. a + b != b + a. Так что только update в нужную сторону, только хардкор.
            Ответить
            • из-за одинаковых ключей?
              Ответить
              • Да. Из-за этого от направления результат зависит.
                Ответить
            • Но сложение списков и кортежей тоже неассоциативное...
              Ответить
              • Да, не подумал.
                Ответить
                • чет я не могу врубиться к чему вы вообще об этом заговорили. Если об операторах - так можно перегрузить как хочешь. А если алгебру на словарях хотите, то причем тут списки?
                  Ответить
                  • Ну я думал, что + для словарей не запилили чтобы не нарушать свойства +. Но забыл про то, что этот самый + уже и для списков и для строк наперегружали, и никаких свойств у него уже и нету...

                    > так можно перегрузить как хочешь
                    И получить кресты-бусты с выводом через << и поклейкой путей через /.
                    Ответить
                    • да, группа не абелева как не крути

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

                          Вот, например, если считать, что A - B == A, A != B; A - B == '', A == B:
                          str = 'test.com'
                          LETTERS = - 'a' - 'b' - ... - 'z'
                          matched = '' == str + LETTERS + LETTERS + LETTERS - '.' + 4 * LETTERS

                          А симметрично можно?
                          Ответить
                    • >поклейкой путей через /.
                      В питон тоже завезли. Правда, как-то забыли, что пути обычно берутся копипастом откуда-то.
                      Ответить
            • > a + b != b + a
              Можно складывать в сумму минимум значений с одинаковым ключом.
              Долго считается, но зато симметрично.
              Ответить
              • так и сложение не всегда коммутативно. Например сложение строк
                Ответить
                • Нету сложения строк, есть конкатенация. Просто её в некоторых языках обозначили плюсиком.
                  Ответить
                  • темболее
                    Ответить
                  • Но если подчитать литературу, то у строк есть не только отнимание, но и уможение, и деление, при чем как справа, так и слева... и еще куча других операций.
                    Ну, в смысле, эти операции не существуют в каком-то абсолютном смысле. Просто кому-то захотелось определить так, вот и определили.
                    Из интересных вещей: можно найти параллель между конечными автоматами и производящими функциями последовательности. Ну и можно т.о. говорить о "простоте" строк (в том же смылсе, как есть простые числа, например) и т.д.
                    Ответить
                    • Ну, в общем-то, каждой строке можно сопоставить целое число. Тогда над ними и обычная арифметика будет работать...
                      Ответить
                      • str - ' ' // trim right
                        ' ' - str // trim left
                        ' ' - str - ' ' // trim

                        // Ушёл переопределять операторы для std::string
                        Ответить
                        • А / уже переопределили в boost, чтобы через '/' конкатенировать :)
                          Ответить
                      • Можно даже рациональные сопоставить. Но иррациональные - не очень.
                        Более того, обычная арифметика именно так и определена :) она ж неспроста так работает.
                        Т.е. обычное определение целых как {}, {{}}, {{{}}}, {{{}},{}} и т.д. - это ж определение строк. Просто когда говорим про строки то нас интересует один вид операций, а когда про числа - другой.

                        Вот чего для более полноценной работы со строками в языках программирования не хватает, так это алфавитов и операций над множествами для регулярных выражений.
                        Ответить
                        • Ну в общем-то std::basic_string из крестов позволяет составлять строки из произвольных алфавитов, достаточно char_traits для них описать...
                          Ответить
                          • Можно, по идее, даже сделать строку из функций. Или что-нибудь с бесконечным алфавитом (ну ок, ограниченным памятью).
                            Ответить
              • Тогда у тебя операция необратимой станет, опять до сложения не вытянешь :)
                Ответить

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