Как разбить линию цепных методов в 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 символов в этой ситуации. Есть ли лучший способ сломать его (желательно без обратных косых черт)?

8 96

8 ответов:

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

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()
    )

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

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, это может быть признаком того, что есть проблемы с читаемостью, которые выходят за рамки вашего выбора пробелов :-)

мой личный выбор такой:

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()

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

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()

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

это немного другое решение, чем у других, но мое любимое, так как оно иногда приводит к изящному метапрограммированию.

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()

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

вы, кажется, используете 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()

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

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)