Що є хорошим способом замовлення методів у класі Python?


86

Я хочу впорядковувати методи в класі Python, але не знаю, який правильний порядок.

Коли я видобуваю методи в Eclipse за допомогою PyDev, Eclipse ставить витягнутий метод поверх модифікованого методу. Але це ставить деталі нижчого рівня перед деталями більш високого рівня. За словами дядька Боба, я мав би зробити навпаки, щоб мій код читався як заголовки газет. Коли я програмую Java, я просто виконую його поради.

Яка найкраща практика для Python?


8
Не існує найкращої практики. Робіть те, що має найбільший сенс - важливі речі вгорі - це гарна ідея, а послідовність - це, як правило, гарна річ. PEP-8 про це не згадує, і якби це було встановлено в камені, ось де б воно було.
Gareth Latty

4
І навіть PEP8 не завжди встановлений у камені.
Ігнасіо Васкес-Абрамс

1
Зазвичай я роблю це за групою щодо функціональності (отримати, встановити тощо)
CppLearner

Важливо зазначити, що порядок функцій методу може бути довільним, оскільки оголошення класу лише визначає його функції методу, а не викликає їх. Це дозволяє вихідному коду підпрограм методів класу успішно використовувати функції методів, які будуть визначені далі в списку.
DragonLord

Відповіді:


64

Як зазначали інші, немає правильного способу замовити ваші методи. Можливо, пропозиція PEP була б корисною, але в будь-якому випадку. Дозвольте мені спробувати підійти до Вашого питання якомога об’єктивніше.

  • Спочатку інтерфейси: Відкриті методи та магічні функції Python визначають інтерфейс класу. Здебільшого ви та інші розробники хочете використовувати клас, а не змінювати його. Таким чином, їх зацікавить інтерфейс цього класу. Поміщення його першим у вихідному коді дозволяє уникнути прокрутки деталей реалізації, які вас не хвилюють.

  • Властивості, магічні методи , загальнодоступні методи: важко визначити найкращий порядок між цими трьома, які всі є частиною інтерфейсу класу. Як каже @EthanFurman, найважливіше дотримуватися однієї системи для всього проекту. Як правило, люди розраховують __init__()на найкращу першу функцію в класі, тому я продовжую роботу з іншими магічними методами прямо нижче.

  • Порядок читання: В основному є два способи розповісти історію: знизу вгору або зверху вниз. Поставивши на перший план функції високого рівня, розробник може приблизно зрозуміти клас, прочитавши перші пару рядків. В іншому випадку потрібно було б прочитати весь клас, щоб зрозуміти клас, і більшість розробників не мають на це часу. Як правило, методи ставлять вище всіх методів, що викликаються з їхнього тіла.

  • Методи класів та статичні методи: Зазвичай це передбачається описаним вище порядком читання . Звичайні методи можуть викликати всі методи часу і, отже, на першому місці. Методи класу можуть викликати лише методи класу та статичні методи, і вони йдуть далі. Статичні методи не можуть викликати інші методи класу і йдуть останніми.

Сподіваюся, це допомагає. Більшість цих правил, до речі, не є специфічними для Python. Я не знаю мови, яка застосовує порядок методів, але якщо так, це було б досить цікаво, і будь ласка, коментуйте.


1
Зазвичай мова не забезпечує впорядкування. Але деякі мови мають загальноприйняті умови. Наприклад, C # StyleCop має суворі правила впорядкування. Щодо Java див stackoverflow.com/questions/4668218 і т.д.
xmedeko

1
Методи класу: їх часто використовують як конструктори, і тоді вони, як правило, викликають __init__явно (у поєднанні з __new__) або неявно (через конструктор за замовчуванням), так що це буде причиною розміщувати їх разом з __init__. (Хоча я ніколи не бачив , як вони розміщені , перш __init__ тим .)
oulenz

13

Немає одного правильного наказу. Виберіть систему і дотримуйтесь її. Я використовую:

class SomeClass(object):
    def __magic_methods__(self):
        "magic methods first, usually in alphabetical order"
    def _private_method(self):
        "worker methods next, also in alpha order"
    def a_method(self):
        "then normal methods, also in alpha order"

2
Які переваги ви надаєте staticmethods, змінним класу та @property-декорованим методам?
Джон Мі

@JohnMee: змінні класу, які я ставлю перед іншим; мій складаний метод приховує @staticmethod, @classmethod, @propertyі будь-які інші @decoratorрядки , тому я використовую тип методу , щоб визначити , де він йде (за винятком того, що властивості мають тенденцію йти між _private_methodsі normal_methods).
Ітан Фурман,

Отже, якщо порядок в основному переходить від дуже приватних "магічних" методів до приватних до звичайних, чи означає це, що @classmethods йде наступним ( @classmethod def a_class_method(cls)), то @staticmethods ( @staticmethod def a_static_method())? Принаймні така політика, наскільки я її розумію ... (без того, щоб моя IDE нічого не складала, бо мені це не подобається)
Каву

2

Я роблю щось подібне до @Ethan, що я бачив у джерелі Django, де головна відмінність - велика "############" коментація блоків для розмежування областей. Наприклад,

class SomeClass(object):
    #################
    # Magic Methods #
    #################
    def __magic_methods__(self):
        "magic methods first"

    ##################
    # Public Methods #
    ##################
    def a_method(self):
        "then normal methods, in order of importance"

    ###################
    # Private Methods #
    ###################
    def _private_method(self):
        "then worker methods, grouped by importance or related function"

Очевидно, це менш корисно для менших класів.


19
Але я бачу, що вони магічні, державні чи приватні. Я сам активно не люблю такі блоки коментарів; Я можу подивитися на складений код, якщо хочу побачити їх список. Маючи коментар над певним блоком методів, пов’язаних з функціональністю, я б щось зробив, але для цього типу коментарів - це те, що говорять назви методів.
Chris Morgan

Знову ж таки, я роблю це лише для більших класів. Я вважаю, що легко переплутати магічні методи з напівприватними ( ) та спотвореними іменами (_ ) методами.
Метт Луонго,

Я в середині редагування видаляв потворні ####блоки, коли зрозумів, що ти їх спеціально помістив ! Однак я погоджуюся з наказом , саме про це йдеться в цьому питанні. Я б рекомендував вилучити ####з цього прикладу, оскільки він не відноситься до обсягу питання, і ваш приклад має невеликий клас, для якого ви б і так не користувалися ####. :-)
Mateen Ulhaq

1
@MateenUlhaq, будь ласка, зверніться до другого та п’ятого керівних принципів, що відображаються на екрані редагування: "уточнюйте значення, не змінюючи його" та " завжди поважайте оригінального автора". (Зверніть увагу, що вони мають застосовуватися безумовно, не враховуючи власної думки редактора.) Цілою і єдиною метою цієї відповіді було відображення тих потворних блоків коментарів; без них це говорить точно те саме, що відповідь Ітана, і немає сенсу тут бути. Ви навіть визнали, що блоки були там " навмисно " - знаючи це, чому ви підете та вилучите їх?
привіт

1
@MIWright Я думав, що це виходить за рамки питання. Як бачите, rev2 все ще містить матеріал, який відповідає на запитання інакше, ніж на питання Ітана, з іншим упорядкуванням (і підпорядкуванням!). Тим не менше, відкотився назад.
Mateen Ulhaq,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.