Соответствует ли поздняя привязка философии «читабельности»? - PullRequest
1 голос
/ 11 января 2009

Я прошу прощения у всех - я здесь не виноват Питон. Это просто отражение того, правильно ли то, что я считаю. Будучи преданным Python в течение двух лет, я писал только небольшие приложения и хвалил Python везде, куда бы я ни шел. Недавно у меня была возможность прочитать код Django, и я начал задаваться вопросом, действительно ли Python следует своей философии «количества читабельности». Например,

class A:
    a = 10
    b = "Madhu"

    def somemethod(self, arg1):
        self.c = 20.22
        d = "some local variable"
        # do something
        ....
        ...
    def somemethod2 (self, arg2):
        self.c = "Changed the variable"
        # do something 2
        ...

Трудно отследить поток кода в ситуациях, когда переменные экземпляра создаются при использовании (то есть self.c в приведенном выше фрагменте). Невозможно увидеть, какие переменные экземпляра определены при чтении значительного количества кода, написанного таким образом. Это становится очень неприятно даже при чтении класса с 6-8 методами и не более 100-150 строк кода.

Мне интересно знать, искажено ли мое чтение этого кода в стиле C ++ / Java, поскольку большинство других языков придерживаются того же подхода, что и они. Есть ли Pythonic способ чтения этого кода более свободно? Что заставило разработчиков Python принять эту стратегию, помня о «читабельности»?

Ответы [ 8 ]

14 голосов
/ 12 января 2009

Фрагмент кода, который вы представляете, довольно нетипичен (что может быть и потому, что вы, вероятно, сделали его):

  • у вас обычно не было бы переменной экземпляра (self.c), которая в некоторой точке представляет собой число с плавающей точкой, а в другой - строку. Это должно быть либо число, либо строка все время.

  • обычно вы не вносите переменные экземпляра в жизнь произвольным методом. Вместо этого у вас обычно есть конструктор (__init__), который инициализирует все переменные.

  • у вас обычно нет переменных экземпляра с именами a, b, c. Вместо этого у них есть несколько говорящих имен.

С этими исправлениями ваш пример будет гораздо более читабельным.

5 голосов
/ 12 января 2009

Достаточно талантливый негодяй может написать нечитаемый код на любом языке. Python пытается навязать некоторые правила для структуры и именования, чтобы подтолкнуть кодеров в правильном направлении, но нет способа заставить это сделать.

Для чего бы то ни было, я стараюсь ограничить область действия локальных переменных областью, в которой они используются на каждом языке, который я использую - для меня отсутствие необходимости поддерживать огромный ментальный словарь гораздо легче познакомиться с небольшим количеством кода.

3 голосов
/ 12 января 2009

Эта проблема легко решается путем указания стандартов кодирования, таких как объявление всех переменных экземпляра в методе init вашего объекта. На самом деле это не проблема для Python, а для программиста.

3 голосов
/ 12 января 2009

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

В своем собственном коде вы должны применять любые условные обозначения, облегчающие поддержание кода. Что касается этой конкретной проблемы, существует ряд возможных вещей, которые могут помочь.

  • Используя что-то вроде Epydoc , вы можете указать все переменные экземпляра, которые будут иметь класс. Внимательно относитесь к документированию своего кода и не менее скрупулезно следите за тем, чтобы ваш код и документация оставались синхронизированными.
  • Примите соглашения о кодировании, которые поощряют тот тип кода, который вам проще всего поддерживать. Нет ничего лучше, чем подавать хороший пример.
  • Держите ваши классы и функции маленькими и четкими. Если они становятся слишком большими, разбейте их. Проще понять, что происходит таким образом.
  • Если вы действительно хотите настаивать на том, чтобы переменные экземпляра объявлялись до обращения к ним, есть некоторые приемы метакласса, которые вы можете использовать. Например, вы можете создать общий базовый класс, который, используя логику метакласса, обеспечивает соблюдение соглашения о том, что позднее могут быть установлены только переменные, которые объявлены при объявлении подкласса.
2 голосов
/ 12 января 2009

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

2 голосов
/ 12 января 2009

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

2 голосов
/ 11 января 2009

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

Это только мое мнение.

0 голосов
/ 12 января 2009

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

...