Подтвердить что ты не робот

Используете ли вы Python в основном для его функциональных или объектно-ориентированных функций?

Я вижу, что большинство разработчиков Python на StackOverflow одобряют использование сжатых функциональных инструментов, таких как lambdas, карты, фильтры и т.д., в то время как другие говорят, что их код более ясен и удобен в обслуживании, не используя их. Каковы ваши предпочтения?

Кроме того, если вы являетесь программистом-программистом или хардкором в OO, какие другие конкретные методы программирования вы используете, которые, по вашему мнению, лучше всего подходят для вашего стиля?

Заранее благодарим за ваши мнения!

4b9b3361

Ответ 1

В основном я использую Python с использованием объектно-ориентированных и процедурных стилей. Python на самом деле не особенно хорошо подходит для функционального программирования.

Многие думают, что они пишут функциональный код Python, используя множество lambda, map, filter и reduce, но это немного упрощено. Особенностью функционального программирования является отсутствие состояния или побочных эффектов. Важными элементами функционального стиля являются чистые функции, рекурсивные алгоритмы и функции первого класса.

Вот мои мысли о функциональном программировании и Python:

  • Чистые функции велики. Я делаю все возможное, чтобы мои функции на модульном уровне были чистыми.

    • Чистые функции могут быть протестированы. Поскольку они не зависят от внешнего состояния, их намного легче проверить.
    • Чистые функции могут поддерживать другие оптимизации, такие как memoization и тривиальная распараллеливание.
  • Программирование на основе классов может быть чистым. Если вам нужен эквивалент чистым функциям с использованием классов Python (что иногда, но не всегда, что вы хотите),

    • Сделайте ваши экземпляры неизменными. В частности, это в основном означает, что ваши методы всегда возвращают новые экземпляры вашего класса, а не меняют текущий.
    • Использовать инъекцию зависимостей, а не получать материал (например, импортированный модуль) из глобальной области.
    • Это не всегда может быть именно то, что вы хотите.
  • Не пытайтесь избежать состояния вместе. Это не разумная стратегия в Python. Например, используйте some_list.append(foo), а не new_list = some_list + [foo], первая из которых более идиоматична и эффективна. (Действительно, тонна "функциональных" решений, которые я вижу, что люди используют в Python, алгоритмически субоптимальна по сравнению с просто-простыми или более простыми решениями, которые не являются функциональными или функциональными, но не используют функционально выглядящие инструменты. )

  • Изучите лучшие уроки функционального программирования, например изменяемое состояние опасно. Задайте себе вопрос: действительно ли я хочу изменить этот X или мне нужен новый X?

    • Одно действительно обычное место, которое возникает при обработке списка. Я бы использовал

      foo = [bar(item.baz()) for item in foo]
      

      а не

      for index, _ in enumerate(foo):
          foo[index] = bar(foo[index].baz())
      

      и тому подобное. Это позволяет избежать путаных ошибок, когда один и тот же объект списка хранится в другом месте и не должен изменяться. (Если он должен быть изменен, тогда есть приличная вероятность, что у вас есть ошибка дизайна. Мутирование некоторых списков, на которые вы ссылались на несколько мест, не является отличным способом совместного использования состояния.)

  • Не используйте map и друзей безвозмездно. Нет ничего более функционального в этом.

    • map/filter не более функциональные, чем списки. Список понятий был заимствован из Haskell, чистого функционального языка. map и особенно filter может быть сложнее понять, чем понимание списка. Я бы никогда не использовал map или filter с лямбдой, но мог бы, если бы у меня была уже существующая функция; Я использую map приличный бит.
    • То же самое относится к itertools.imap/ifilter по сравнению с выражениями генератора. (Эти вещи несколько ленивы, что является чем-то большим, что мы можем заимствовать из функционального мира.)
    • Не используйте map и filter для побочных эффектов. Я вижу это с map много, что делает сложный код, ненужные списки и явно не работает (несмотря на то, что люди думают, что это должно быть из-за map.) Просто используйте цикл for.
    • reduce запутан, за исключением очень простых случаев. У Python есть петли, и нет никакого вреда в их использовании.
  • Не используйте рекурсивные алгоритмы. Это одна часть функционального программирования. Python просто не поддерживает. CPython (и я думаю, что все остальные Python) не поддерживают оптимизацию хвостовых вызовов. Вместо этого используйте итерацию.

  • Используйте только lambda, когда вы определяете функции "на лету". Анонимные функции не лучше, чем именованные функции, последние из которых часто более надежны, поддерживаются и документируются.

Ответ 2

Я использую возможности языка, которые выполняют работу с самым коротким, самым чистым кодом. Если это означает, что мне нужно смешать два, что я делаю довольно часто, то что будет сделано.

Ответ 3

Я оба умный ООП и функциональный программист, и эти стили работают очень хорошо вместе, главным образом потому, что они полностью ортогональны. Существует много объектно-ориентированных функциональных языков, и Python является одним из них.

В принципе, разложение приложения на классы очень полезно при разработке системы. Когда вы выполняете фактическую реализацию, FP помогает написать правильный код.

Также я нахожу очень оскорбительным, что вы подразумеваете, что функциональное программирование просто означает "использовать складки повсюду". Это, вероятно, самое большое и худшее заблуждение относительно FP. Многое было написано по этой теме, поэтому я просто скажу, что великой вещью в FP является идея объединить простые (, правильные и многоразовые) функции в новую, все более сложную функцию. Таким образом, довольно сложно написать "почти правильный" код - либо все делает именно то, что вы хотите, либо полностью ломается.

FP в Python в основном вращается вокруг написания генераторов и их родственников (список понятий) и вещей в модуле itertools. Явные вызовы map/filter/reduce просто не нужны.

Ответ 4

Python имеет только незначительные функциональные функции программирования, поэтому я был бы удивлен, если бы многие люди использовали его специально для этого. Например, нет стандартного способа выполнения композиции функций, а стандартная библиотека reduce() устарела в пользу явных циклов.

Кроме того, я не думаю, что map() или filter() обычно поддерживаются. В противоположность, обычно предпочтительнее понимать список.

Ответ 5

Большинство ответов на StackOverflow - короткие, сжатые ответы, а функциональные аспекты python упрощают запись таких ответов.

Функции Python OO просто не нужны в ответах 10-20 строк, поэтому вы не видите их здесь.

Ответ 6

Я выбираю Python, когда беру на себя проблему, которая хорошо отображает решение OO. Python обеспечивает ограниченную способность программировать функционально, по сравнению с полнофункциональными функциональными языками.

Если мне действительно нужно функциональное программирование, я использую Lisp.