Как разбить цепочку методов в Python? - PullRequest
119 голосов
/ 22 января 2011

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

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 ]

225 голосов
/ 22 января 2011

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

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()
    )
47 голосов
/ 09 апреля 2013

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

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

13 голосов
/ 22 января 2011

Мой личный выбор будет:

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()
10 голосов
/ 22 января 2011

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

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()
4 голосов
/ 02 октября 2015

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

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

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

3 голосов
/ 22 января 2011

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

1 голос
/ 13 марта 2017

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

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)
1 голос
/ 22 января 2011

Вы, похоже, используете 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()
...