Как правильно создать класс утилиты

У меня есть файл, который должен быть файлом утилиты. Файл должен содержать много статических методов.

Должен ли я определять методы внутри класса таким образом:

#utility.py
class utility(object):
    @staticmethods
    def method1(a,b,c):
        pass

    @staticmethods
    def method2(a,b,c):
        pass

или использовать его так (без класса):

#utility.py
def method1(a,b,c):
    pass

def method2(a,b,c):
    pass

Ответы

Ответ 1

Второй вариант - это modus operandi в Python. Я имею в виду, если все, что вы делаете, это импорт функций, вы можете сделать что-то вроде этого:

from utility import some_func

который будет импортировать вашу функцию.

Лучшая практика заключается в том, что вы используете только статические функции, а затем просто помещаете их в глобальное пространство имен отдельного модуля, это сделает вашу жизнь намного проще. То, что вы пытаетесь сделать, это создавать объекты и просто заполнять их статическими методами. Зачем это делать, когда вы можете просто определить функции в файле .py?

На самом деле то, что вы пытаетесь сделать, сделано. Вы пытаетесь сохранить некоторые полезные функции утилиты. Ну, python-requests, это сторонняя библиотека, которая просто обожает большинство Pythonistas, просто делает это. Он сохраняет свои полезные функции в отдельном модуле. Вот пример.

Ответ 2

Классы инкапсулируют как данные, так и поведение, так как общие правила:

  • Если у вас есть что-то только с данными и без методов, вероятно, это будет namedtuple, а не class, если вам не нужно будет изменять эти данные после его создания.
  • Если функция обращается к данным экземпляра, это должен быть метод.
  • Если функция не обращается к данным экземпляра, но делает данные класса доступа, она должна быть @classmethod.
  • Если функция не обращается ни к данным экземпляра, ни к данным класса, она должна быть автономной функцией, если нет какой-либо действительно веской причины сделать ее @staticmethod.
  • Если a class имеет только один метод или один метод в дополнение к __init__(), то вы почти наверняка можете и должны переписать его как функцию.

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

Ответ 3

Хотя этот вопрос немного основан на мнении, я бы сказал, что второй лучше. Это уменьшает избыточность. Используя первый метод, вам нужно будет:

import utility
utility.utility.method1(...)

или

from utility import utility
utility.method1(...)

Использование второго, однако, позволяет вам просто:

import utility
utility.method1(...)

или

from utility import method1
method1(...)

Если вы создаете класс, содержащий только статические методы, мой вопрос: "Почему вам нужен класс?" Это ничего не дает положительного результата.