Как разбить линию цепочечных методов в Python?

У меня есть строка следующего кода (не обвиняйте в соглашениях об именах, они не мои):

subkeyword = Session.query(
    Subkeyword.subkeyword_id, Subkeyword.subkeyword_word
).filter_by(
    subkeyword_company_id=self.e_company_id
).filter_by(
    subkeyword_word=subkeyword_word
).filter_by(
    subkeyword_active=True
).one()

Мне не нравится, как это выглядит (не слишком читаемо), но у меня нет лучшей идеи ограничить строки до 79 символов в этой ситуации. Есть ли лучший способ его разлома (желательно без обратной косой черты)?

Ответ 1

Вы можете использовать дополнительные скобки:

subkeyword = (
        Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_word)
        .filter_by(subkeyword_company_id=self.e_company_id)
        .filter_by(subkeyword_word=subkeyword_word)
        .filter_by(subkeyword_active=True)
        .one()
    )

Ответ 2

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

subkeyword = Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_word) \
                    .filter_by(subkeyword_company_id=self.e_company_id)          \
                    .filter_by(subkeyword_word=subkeyword_word)                  \
                    .filter_by(subkeyword_active=True)                           \
                    .one()                                                       \

PEP 8 намеревается интерпретировать с мерой здравого смысла и глаза как для практического, так и для красивого. С радостью нарушайте любое руководство PEP 8, которое приводит к уродливому или трудно читаемому коду.

Если вы считаете, что часто встречаетесь с PEP 8, это может быть признаком того, что есть проблемы с читабельностью, которые превосходят ваш выбор пробелов: -)

Ответ 3

Мой личный выбор:

subkeyword = Session.query(
    Subkeyword.subkeyword_id,
    Subkeyword.subkeyword_word,
).filter_by(
    subkeyword_company_id=self.e_company_id,
    subkeyword_word=subkeyword_word,
    subkeyword_active=True,
).one()

Ответ 4

Просто сохраните промежуточный результат/объект и вызовите на нем следующий метод, например.

q = Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_word)
q = q.filter_by(subkeyword_company_id=self.e_company_id)
q = q.filter_by(subkeyword_word=subkeyword_word)
q = q.filter_by(subkeyword_active=True)
subkeyword = q.one()

Ответ 5

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

Ответ 6

Это немного другое решение, чем другие, но мой любимый, поскольку он иногда приводит к отличному метапрограммированию.

base = [Subkeyword.subkeyword_id, Subkeyword_word]
search = {
    'subkeyword_company_id':self.e_company_id,
    'subkeyword_word':subkeyword_word,
    'subkeyword_active':True,
    }
subkeyword = Session.query(*base).filter_by(**search).one()

Это хороший метод для поиска. Перейдите по списку условных выражений к моей из вашей сложной формы запроса (или строковым выводам о том, что ищет пользователь), а затем просто взорвите словарь в фильтр.

Ответ 7

Кажется, вы используете SQLAlchemy, если это правда, sqlalchemy.orm.query.Query.filter_by() метод принимает несколько аргументов ключевого слова, поэтому вы можете писать так:

subkeyword = Session.query(Subkeyword.subkeyword_id,
                           Subkeyword.subkeyword_word) \
                    .filter_by(subkeyword_company_id=self.e_company_id,
                               subkeyword_word=subkeyword_word,
                               subkeyword_active=True) \
                    .one()

Но было бы лучше:

subkeyword = Session.query(Subkeyword.subkeyword_id,
                           Subkeyword.subkeyword_word)
subkeyword = subkeyword.filter_by(subkeyword_company_id=self.e_company_id,
                                  subkeyword_word=subkeyword_word,
                                  subkeyword_active=True)
subkeuword = subkeyword.one()

Ответ 8

Мне нравится отступать от аргументов двумя блоками и оператором одного блока, например:

for image_pathname in image_directory.iterdir():
    image = cv2.imread(str(image_pathname))
    input_image = np.resize(
            image, (height, width, 3)
        ).transpose((2,0,1)).reshape(1, 3, height, width)
    net.forward_all(data=input_image)
    segmentation_index = net.blobs[
            'argmax'
        ].data.squeeze().transpose(1,2,0).astype(np.uint8)
    segmentation = np.empty(segmentation_index.shape, dtype=np.uint8)
    cv2.LUT(segmentation_index, label_colours, segmentation)
    prediction_pathname = prediction_directory / image_pathname.name
    cv2.imwrite(str(prediction_pathname), segmentation)