파이썬에서 일련의 체인 메소드를 끊는 방법?


139

다음 코드 줄이 있습니다 (이름 지정 규칙을 비난하지 말고 내 것이 아닙니다).

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 자로 제한하는 더 좋은 아이디어는 없습니다. 더 나은 방법은 있습니까 (바람직하게는 백 슬래시가 없는가)?

답변:


257

추가 괄호를 사용할 수 있습니다.

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

나는 또한 그것을 가장 좋아합니다. 더 많은 코드를 추가하지 않으며 백 슬래시가 없습니다.
Juliusz Gonera

22
여분의 들여 쓰기를 정당화하는 것이 확실하지 않습니다. 나는이 솔루션이 단 한 번 들여 쓰기 된 행과 후미가있는 파엔으로도 읽히지 않는다고 생각합니다.
Carl Meyer

4
내 의견으로는 이중 들여 쓰기는 일반적인 들여 쓰기 블록과 시각적으로 다르기 때문에 여기서 유용합니다. 다른 코드로 둘러싸여 있으면 줄 바꿈 된 것이 더 분명합니다.
sth

1
Parens 사용 측면에서 가장 좋은 답변입니다. 다른 답변에서 Shanimal의 의견에서 언급했듯이 괄호를 통한 묵시적 행 연속 사용은 실제로 PEP 8 선호 되고 연속 문자``
kevlarr

백 슬래시를 선호합니다. 괄호는 모든 상황에 대한 힌트가 아닙니다. 예를 들어, 할당 연산자에서는 작동하지 않습니다. 이 체인에서 줄을 끊고 싶다고 상상해보십시오.foo.set_default('bar', {}).set_default('spam', {}).set_default('eggs', {})['lol'] = 'yeah'
loutre

56

괄호를 여는 데 줄 연속 문자가 선호되는 경우입니다. 메소드 이름이 길어지고 메소드가 인수를 시작함에 따라이 스타일의 필요성이 더욱 분명해집니다.

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과 자주 충돌하는 경우 공백 선택을 초월하는 가독성 문제가 있음을 나타낼 수 있습니다. :-)


2
이 특정 경우 백 슬래시에서 +1 및 체인 필터 정렬 이러한 상황은 아니라 장고에서 발생하는 대부분의 읽을 수있는이 방법을 - 그러나에 어떤 내가 괄호 문구 같은 느낌이 다른 상황 우수 (고생하지 않는 "내 백 슬래시 후가 공백인가?"문제). 즉, 문구를 괄호로 묶는 것은 동일한 효과를 얻는 데 사용될 수 있지만 파이썬을 읽는 중간에 Lisp 읽기 모드로 전환됩니다.
zxq9

11
이 방법이 "외부 괄호로 감싸기"또는 "각 열린 깎기 후와 닫히는 깎기 전에 줄 바꿈"보다 "메소드 이름이 길어지고 메쏘드가 인수를 받기 시작함에 따라"이 솔루션이 어떻게 더 잘 대처할 수 있는지 알 수 없습니다. 솔루션. 실제로 (적어도 여기에 표시된 것처럼) 모든 행 라인에 대해 훨씬 더 깊은 들여 쓰기가 필요하기 때문에 처리가 더 나쁩니다.
Carl Meyer

1
필터 호출을 위해 너무 많이 들여 쓰기. 하나의 탭 또는 4 개의 공백으로 충분합니다. 또한``... 그 스페이스 키를 몇 초 동안 누르고 있습니까? 일반적으로 나는 모든 방법에 반대합니다. 내일이없는 것처럼 우주 열쇠를 망치는 것이 필요합니다.
Zelphir Kaltstahl

2
PEP8은 "긴 줄을 줄 바꿈하는 가장 좋은 방법은 괄호, 괄호 및 중괄호 안에 파이썬의 묵시적 줄 연속을 사용하는 것입니다. 긴 줄은 괄호 안에 식을 줄 바꿈하여 여러 줄로 나눌 수 있습니다. 백 슬래시를 사용하는 것보다 우선적으로 사용해야합니다. 줄 연속을 위해. " — Python.org 백 슬래시가 적절한시기에 대해 계속 논의합니다
Shanimal

PEP8에 대한 훌륭한 참조! 여기에 모든 정렬을 가진 성가신 문제 .filter호출을 변경하는 경우이다 subkeywordsub_keyword, 지금의 들여 해결해야 할 모든 단일 라인 이 변수 이름을 변경해서. 스타일이 실제로 유지 보수성을 방해 할 때는 좋지 않습니다 ...
kevlarr

15

내 개인적인 선택은 다음과 같습니다.

하위 키워드 = Session.query (
    하위 키워드 .subkeyword_id,
    하위 키워드.
) .filter_by (
    subkeyword_company_id = self.e_company_id,
    subkeyword_word = subkeyword_word,
    subkeyword_active = 참,
).하나()

1
여러 매개 변수가 전달되는 경우 동의하지만 0 또는 1 매개 변수가 공통 일 때보기에 좋지 않습니다. 예 : gist.github.com/andybak/b23b6ad9a68c7e1b794d
Andy Baker

1
예, 그 스타일은 (모든 스타일과 마찬가지로) 변질 된 사례를 가지고 있습니다. 나는 모든 열린 괄호를 깰 수는 없습니다. 이 중 어느 것도 나를 행복하게 만들지는 않지만 다음과 같은 경우가 있습니다. gist.github.com/pkoch/8098c76614765750f769
pkoch

12

중간 결과 / 객체를 저장하고 다음 메소드를 호출하십시오 (예 :

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

10
이것은 쿼리와 같은 경우에는 잘 작동하지만 일반적인 패턴으로 확실하지 않습니다. 예를 들어, Beautiful Soup에서 체인을 연결할 때 team_members = soup.find(class_='section team').find_all('ul').find_all('li').find(...)호출 의 반환 값 이 team_members아직 의미에 맞지 않습니다.
Taylor Edmiston

1
@TaylorEdmiston 물론 부분 결과에 대해 다른 이름을 가질 수 있습니다. 같은 뭔가 section = soup.find(class_='section team')하고 team_members = section.find_all('ul').find_all('li').
Jeyekomon

4

Python Language Reference 에 따르면
백 슬래시를 사용할 수 있습니다.
아니면 간단히 깨십시오. 대괄호가 쌍을 이루지 않으면 파이썬은 그것을 대괄호로 취급하지 않습니다. 이러한 상황에서 다음 줄의 들여 쓰기는 중요하지 않습니다.


4

때로는 다른 사람들이 제공하는 것과는 약간 다른 해결책이지만 때로는 멋진 메타 프로그래밍으로 이어지기 때문에 내 마음에 드는 것입니다.

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

이것은 검색을 작성하기위한 좋은 기술입니다. 복잡한 쿼리 양식 (또는 사용자가 찾고있는 것에 대한 문자열 기반 추론)에서 채굴하기위한 조건 목록을 살펴본 다음 사전을 필터로 분해하십시오.


1

SQLAlchemy를 사용하는 것 같습니다. true 인 경우 sqlalchemy.orm.query.Query.filter_by()method는 여러 개의 키워드 인수를 사용하므로 다음과 같이 작성할 수 있습니다.

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

SQLAlchemy filter_by () 힌트의 경우 +1 이 예제에는 좋지만 1 개의 조건 만 허용하는 filter ()를 자주 사용합니다.
Juliusz Gonera

1

다음과 같이 인수를 두 블록으로 들여 쓰기하고 한 블록으로 명령문을 들여 쓰는 것을 좋아합니다.

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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.