организация классов и модулей в Python - PullRequest
11 голосов
/ 17 августа 2010

У меня немного болит голова, когда я пытаюсь понять, как организовать модули и классы вместе.Исходя из C ++, я привык к классам, инкапсулирующим все данные и методы, необходимые для обработки этих данных.Однако в python есть модули, и из кода, на который я смотрел, у некоторых людей много свободных функций, хранящихся в модулях, тогда как другие почти всегда связывают свои функции с классами как методы.

Например, скажем, у меня есть структура данных, и я хотел бы записать ее на диск.

Один из способов - реализовать метод сохранения для этого объекта, чтобы я мог просто набрать

MyObject.save(filename)

или что-то типа того.Другой метод, который я видел в равной пропорции, - это получить что-то вроде

from myutils import readwrite

readwrite.save(MyObject,filename)

Это небольшой пример, и я не уверен, насколько конкретно эта проблема связана с python, но мой общий вопрос в том, чтолучшая практика питонов с точки зрения функций и методов организации?

Ответы [ 2 ]

13 голосов
/ 17 августа 2010

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

так что если у меня есть модуль foo.py:

import pprint

def show(obj):
    pprint(obj)

Тогда когда я импортирую его из bar.py

import foo

class fubar(object):
   #code

   def method(self, obj):
       #more stuff
       foo.show(obj)

По сути, я обращаюсь к методу объекта foo. Атрибуты данных модуля foo являются только глобальными переменными, которые определены в foo. Модуль - это реализация синглтона на уровне языка без необходимости добавлять self к каждому списку аргументов методов.

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

Рациональное обоснование точного примера, который вы привели, заключается в том, что если у каждого класса есть метод сохранения, то если вы позже измените способ сохранения данных (от, скажем, файловой системы до базы данных или удаленного XML-файла), вам придется изменить каждый класс , Если каждый класс реализует интерфейс для получения тех данных, которые он хочет сохранить, то вы можете написать одну функцию, чтобы сохранить экземпляры каждого класса и изменить эту функцию только один раз. Это известно как принцип единой ответственности: у каждого класса должна быть только одна причина для изменения.

3 голосов
/ 17 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...