Как программист Java, изучающий Python, что я должен искать?

Большая часть моего фона программирования находится на Java, и я все еще выполняю большую часть своих программ на Java. Тем не менее, я начинаю изучать Python для некоторых побочных проектов на работе, и я хотел бы изучить его как независимый от моего фона Java, насколько это возможно - то есть я не хочу просто программировать Java на Python. Какие вещи я должен искать?

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

Кто-то также предоставил мне этот список, который я нашел полезным, но короткий. У кого-нибудь есть другие примеры того, как Java-программист может неправильно использовать Python...? Или вещи, которые программист Java ошибочно предполагал или имел проблемы с пониманием?

Изменить: Хорошо, краткий обзор причин, затронутых в статье I, связанной с тем, чтобы предотвратить дублирование ответов (как это предложил Билл Ящерица). (Пожалуйста, дайте мне знать, если я ошибаюсь в формулировке, я только начал с Python, поэтому я не могу полностью понять все концепции. И отказ от ответственности - это будет очень кратким, поэтому, если вы не понимаете что он получает, чтобы проверить ссылку.)

  • Статический метод в Java не переводит на класс класса Python
  • Оператор switch в Java переводит на хеш-таблицу в Python
  • Не используйте XML
  • Геттеры и сеттеры злы (эй, я просто цитирую:))
  • Копирование дублирования часто является необходимым злом в Java (например, перегрузка метода), но не в Python

(И если вы находите этот вопрос вообще интересным, проверьте ссылку в любом случае.:) Это довольно хорошо.)

Ответ 1

  • Не помещайте все в классы. Встроенный список Python и словари доставят вас далеко.
  • Не беспокойтесь о сохранении одного класса в модуле. Разделяйте модули по назначению, а не по классу.
  • Использовать наследование для поведения, а не интерфейсов. Не создавайте класс "Animal" для "Dog" и "Cat" для наследования, так что вы можете иметь общий метод "make_sound".

Просто сделайте следующее:

class Dog(object):
    def make_sound(self):
        return "woof!"

class Cat(object):
    def make_sound(self):
        return "meow!"

class LolCat(object):
    def make_sound(self):
        return "i can has cheezburger?"

Ответ 2

В приведенной статье есть несколько полезных советов, которые можно легко интерпретировать и неправильно понимать. И некоторые плохие советы.

Оставьте Java позади. Начните свежие. "Не доверяйте своим [основанным на Java] инстинктам". Высказывание вещей "противоречит интуиции" - это плохая привычка в любой дисциплине программирования. Когда вы изучаете новый язык, начинайте все сначала и бросайте свои привычки. Ваша интуиция должна быть неправильной.

Языки разные. В противном случае они были бы на одном языке с различным синтаксисом, и были бы простые переводчики. Поскольку нет простых переводчиков, нет простого сопоставления. Это означает, что интуиция бесполезна и опасна.

  • "Статический метод в Java не переводит на класс класса Python". Такие вещи действительно ограничены и бесполезны. Python имеет staticmethod декоратор. Он также имеет classmethod decorator, для которого Java не имеет эквивалента.

    Этот момент, BTW, также включал в себя гораздо более полезные советы о том, чтобы не навязывать все вещи в классе. "Идиоматический перевод статического метода Java обычно является функцией уровня модуля".

  • Оператор Java switch в Java может быть реализован несколькими способами. Прежде всего, это обычно конструкция if elif elif elif. В этом отношении статья бесполезна. Если вы абсолютно уверены, что это слишком медленно (и может это доказать), вы можете использовать словарь Python как немного более быстрое сопоставление от значения к блоку кода. Слепо переводчик на словарь (без мышления) - действительно плохой совет.

  • Не используйте XML. Не имеет смысла, когда выведен из контекста. В контексте это означает, что вы не должны полагаться на XML, чтобы добавить гибкость. Java опирается на описание материала в XML; Файлы WSDL, например, повторяют информацию, которая очевидна при проверке кода. Python полагается на интроспекцию вместо того, чтобы переводить все в XML.

    Но у Python отличные библиотеки обработки XML. Несколько.

  • Getters и seters не требуются в Python так, как они требуются в Java. Во-первых, у вас есть лучшая интроспекция в Python, поэтому вам не нужны геттеры и сеттеры, чтобы создавать динамические объекты bean. (Для этого вы используете collections.namedtuple).

    Однако у вас есть декоратор property, который свяжет геттеры (и сеттеры) с конструкцией, подобной атрибуту. Дело в том, что Python предпочитает обнаженные атрибуты; при необходимости мы можем связать геттеры и сеттеры, чтобы они выглядели так, как будто есть простой атрибут.

    Кроме того, у Python есть классы дескрипторов, если свойства недостаточно сложны.

  • Повторение кода часто является необходимым злом в Java (например, перегрузка метода), но не в Python. Верный. Python использует необязательные аргументы вместо перегрузки метода.

    В пулевой точке говорилось о закрытии; это не так полезно, как простой совет по разумному использованию значений аргументов по умолчанию.

Ответ 3

Одна вещь, которую вы могли бы использовать в Java, которую вы не найдете в Python, - это строгое соблюдение конфиденциальности. Это не так много, что нужно искать, поскольку это не нужно искать (я смущен тем, как долго я искал эквивалент Python для 'private', когда я начал!). Вместо этого Python обладает гораздо большей прозрачностью и более легкой интроспекцией, чем Java. Это подпадает под то, что иногда называют философией "мы все соглашаемся с взрослыми". Существует несколько соглашений и языковых механизмов, которые помогают предотвратить случайное использование "непубличных" методов и т.д., Но весь образ скрытия информации практически отсутствует в Python.

Ответ 4

Самый большой, о котором я могу думать, - это не понимание или не полное использование утиной печати. В Java требуется указать очень явную и подробную информацию о типе вверх. В Python типизация является динамичной и в значительной степени неявной. Философия заключается в том, что вы должны думать о своей программе на более высоком уровне, чем номинальные. Например, в Python вы не используете наследование для замещения модели. Заменяемость появляется по умолчанию в результате утиной печати. Наследование - это только удобство программиста для повторного использования реализации.

Аналогично, питоновская идиома - "просить прощения, не спрашивать разрешения". Явная типизация считается злой. Не проверяйте, имеет ли параметр определенный тип upfront. Просто попробуйте сделать все, что вам нужно, с параметром. Если он не соответствует правильному интерфейсу, он выдает очень четкое исключение, и вы сможете быстро найти проблему. Если кто-то передает параметр типа, который был неожиданно неожиданным, но имеет тот же интерфейс, что и вы ожидали, тогда вы получили гибкость бесплатно.

Ответ 5

Самое главное, из Java POV, - это то, что отлично не делать классы для всего. Существует много ситуаций, когда процедурный подход проще и короче.

Следующее самое главное - вам нужно будет понять, что тип объекта контролирует то, что он может делать; скорее, код контролирует, какие объекты должны быть способны поддерживать во время выполнения (это происходит из-за утиного ввода).

О, и используйте, по возможности, собственные списки и dicts (не настроенные потомки).

Ответ 6

Обрабатываемые исключения в Python отличаются от как они обрабатываются на Java. Хотя в Java совет является использование исключений только для исключительных условий, это не поэтому с Python.

В Python такие вещи, как Iterator, используют механизм исключения, чтобы сигнализировать о том, что больше нет элементов. Но такой дизайн не считается хорошей практикой в ​​Java.

Как говорит Алекс Мартелли в своей книге Python в двух словах механизм исключения с другими языками (и применим к Java) LBYL (Взгляд перед прыжком): заключается в проверке заранее, перед попыткой операции, при всех обстоятельствах, которые могут сделать операцию недействительной.

Где, как и с Python, подход - это EAFP (проще просить прощения, чем разрешение)

Ответ 7

Повествование к "Не использовать классы для всего": обратные вызовы.

Java-метод для выполнения обратных вызовов основан на передаче объектов, реализующих интерфейс обратного вызова (например, ActionListener с помощью метода actionPerformed()). В Python ничего подобного не требуется, вы можете напрямую передавать методы или даже локально определенные функции:

def handler():
   print("click!")
button.onclick(handler)

Или даже лямбда:

button.onclick(lambda: print("click!\n"))