如何在Python中打破一系列链接方法?


137

我有以下代码行(不要怪罪命名约定,它们不是我的):

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个字符。有没有更好的方法来破解它(最好没有反斜杠)?

Answers:


255

您可以使用其他括号:

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 2011年

22
不知道什么原因可以证明此处的额外缩进;我认为此解决方案的读取效果也很好,吊线仅缩进一次,尾随的括号根本没有缩进。
卡尔·梅耶

4
我认为双重缩进在这里很有用,因为它在视觉上与正常的缩进块不同。当被其他代码包围时,这很明显是一条包装的单行。
2016年

1
最好的答案,在使用parens。正如Shanimal在另一个答案中的评论中所提到的那样,使用隐含的通过括号连续的行实际上是PEP 8的首选,而不是使用连续字符``
kevlarr 17-10-12

我更喜欢反斜杠。括号并不是所有情况的提示。例如,它不适用于赋值运算符。想象一下您想打破这个链条中的foo.set_default('bar', {}).set_default('spam', {}).set_default('eggs', {})['lol'] = 'yeah'
界限

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,并对齐链接的过滤器。这种情况也出现在Django中,并且以这种方式最容易理解-但在任何其他情况下,我都觉得带括号的短语比较优越(不要因为“我的反斜杠后是否有空格?”问题而苦恼)。就是说,将短语括起来可以达到相同的效果-但在阅读Python的过程中,它使您处于Lisp阅读模式,这让我感到不安。
zxq9

11
我看不出这种解决方案比“在外部括号中换行”或“在每个打开的paren之后和每个闭合的paren之前换行”能更好地应对“随着方法名称变长和方法开始接受参数”。解决方案。实际上,处理起来更糟,因为(至少如下图所示)每条吊线都需要更深的凹痕。
卡尔·梅耶

1
过滤器调用缩进太多了。一个制表符或4个空格就足够了。还要对齐``... ...您按住那个空格键有几秒钟?通常,我反对所有方式,这要求您像没有明天一样敲击太空钥匙。
Zelphir Kaltstahl

2
后来,PEP8读到“包裹长行的首选方法是在括号,方括号和花括号内使用Python的隐含行连续。通过将表达式包装在括号中,可以将长行折断成多行。应优先使用反斜杠。行的延续。” — Python.org继续讨论何时应该使用反斜线
Shanimal

对PEP8的伟大参考!对齐所有.filter调用的一个烦人的问题是,如果您将更subkeyword改为sub_keyword,则由于更改了变量名,现在必须修复每行的缩进。当样式实际上妨碍了可维护性时,效果不是很好...
kevlarr 17-10-12

15

我个人的选择是:

子关键字= Session.query(
    Subkeyword.subkeyword_id,
    Subkeyword.subkeyword_word,
)。过滤(
    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 2015年

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
泰勒·埃德米斯顿,

1
@TaylorEdmiston当然,您可以为部分结果使用不同的名称。像section = soup.find(class_='section team')team_members = section.find_all('ul').find_all('li')
Jeyekomon

4

根据Python语言参考,
您可以使用反斜杠。
或简单地打破它。如果括号未配对,则python不会将其视为一行。在这种情况下,以下行的缩进无关紧要。


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()方法采用多个关键字参数,因此您可以这样编写:

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

+1表示SQLAlchemy filter_by()提示。对于本示例而言,这很好,但是我经常使用filter()代替,后者仅接受1个条件。
Juliusz Gonera 2011年

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.