【问题标题】:How to split a statement into multiple lines?如何将语句拆分为多行?
【发布时间】:2018-06-07 16:58:48
【问题描述】:

打破以下表达式的第一行(出现在多行)以使其更具可读性的正确 Pythonic 方式是什么:

if props.getProperty("app.auth.idp.strategy") == '' or props.getProperty("app.auth.idp.strategy") == 'saml/simpleSAMLphp' and PROXYING_MECHANISM == "ngrok":
    IDP_STRATEGY = "saml/simpleSAMLphp"
elif props.getProperty("app.auth.idp.strategy") == 'saml/gsuite':
    IDP_STRATEGY = "saml/gsuite"
elif props.getProperty("app.auth.idp.strategy") == 'saml/remote-simpleSAMLphp':
    IDP_STRATEGY = "saml/remote-simpleSAMLphp"
else:
     IDP_STRATEGY = "saml"

【问题讨论】:

  • 在新行之前的每一点添加`\`(转义字符)。
  • 我有时也很难让东西看起来可读,所以我认为一旦完全解决,这将作为参考有用,因此请修复 else 下的缩进以供将来参考。我同意其他 cmet 为重用属性分配变量也会增强此代码。
  • 我只是认为您的示例代码所做的是在大多数情况下按原样分配“...idp.strategy”属性的值,是否有更多潜在的例外作为值的“”或您默认为“saml”的完全不同的值?如果您有“saml/simpleSAMLphp”但 PROXYING_MECHANISM 不是“ngrok”,那么您想要什么结果,因为这会导致“saml”
  • @dparolin:没错,我没有对所有可能的排列进行详尽的检查(我想,我也需要使用一些括号),但 saml 应该是在这种情况下作为默认值正确。

标签: python syntax readability code-readability


【解决方案1】:

重构

我会从不重复调用props.getProperty("app.auth.idp.strategy") 开始。调用一次,您立即就没有理由拆分任何行了。

strategy = props.getProperty("app.auth.idp.strategy")
if not strategy or strategy == 'saml/simpleSAMLphp' and PROXYING_MECHANISM == "ngrok":
    IDP_STRATEGY = "saml/simpleSAMLphp"
elif strategy == 'saml/gsuite':
    IDP_STRATEGY = "saml/gsuite"
elif strategy == 'saml/remote-simpleSAMLphp':
    IDP_STRATEGY = "saml/remote-simpleSAMLphp"
else:
     IDP_STRATEGY = "saml"

续行

对于第一行,您的选项是续行,或者显式:

if not strategy or \
   strategy == 'saml/simpleSAMLphp' and \
   PROXYING_MECHANISM == "ngrok":

或隐式,在括号内:

if (not strategy or
    strategy == 'saml/simpleSAMLphp' and
    PROXYING_MECHANISM == "ngrok"):

使用查找,而不是重复比较

一个更更好的选项是用dict查找替换一长串比较:

strategies = {
    "saml/gsuite": "saml/gsuite",
    "saml/remote-simpleSAMLphp": "saml/remote-simpleSAMLphp",
}
if PROXYING_MECHANISM == "ngrok":
    strategies['saml/simpleSAMLphp'] = 'saml/simpleSAMLphp'

IDP_STRATEGY = strategies.get(props.getProperty("app.auth.idp.strategy"), "saml")

因为dict 的每个键都只是映射到自身,所以您可以用简单的set 查找替换那个

strategies = {
    "saml/gsuite",
    "saml/remote-simpleSAMLphp",
}
if PROXYING_MECHANISM == "ngrok":
    strategies.add('saml/simpleSAMLphp')

IDP_STRATEGY = "saml"

strategy = props.getProperty("app.auth.idp.strategy")
if strategy in strategies:
    IDP_STRATEGY = strategy

选择最后两个中哪一个更易读。 dict 在其定义中更加冗余,但允许对 IDP_STRATEGY 进行单个分配。

【讨论】:

  • 对 OP 试图解决的用例的好答案,不一定是可能出现的其他行延续情况的完美答案,但这些应该包含在我认为的其他问题中,我的当更好的实际解决方案让它们消失时,感觉没有人真正来这里解决理论问题。
【解决方案2】:

根据 PEP8 可能是这样的

if props.getProperty("app.auth.idp.strategy") == '' \
        or props.getProperty("app.auth.idp.strategy") == 'saml/simpleSAMLphp' \
        and PROXYING_MECHANISM == "ngrok":
    IDP_STRATEGY = "saml/simpleSAMLphp"
elif props.getProperty("app.auth.idp.strategy") == 'saml/gsuite':
    IDP_STRATEGY = "saml/gsuite"
elif props.getProperty("app.auth.idp.strategy") == 'saml/remote-simpleSAMLphp':
    IDP_STRATEGY = "saml/remote-simpleSAMLphp"
else:
     IDP_STRATEGY = "saml"

【讨论】:

  • 将此与首先为 props.getProperty("app.auth.idp.strategy") 分配变量相结合看起来最好,但是在双缩进时总会有一种破坏性的外观,但没有什么很容易修复。
  • 您正在展示 PEP-8 的第二选择;当它可用时,隐式行继续优于显式。
【解决方案3】:
prop_var = props.getProperty("app.auth.idp.strategy")    
if prop_var == '' or prop_var == 'saml/simpleSAMLphp' and PROXYING_MECHANISM == "ngrok":
        IDP_STRATEGY = "saml/simpleSAMLphp"
    elif prop_var == 'saml/gsuite':
        IDP_STRATEGY = "saml/gsuite"
    elif prop_var == 'saml/remote-simpleSAMLphp':
        IDP_STRATEGY = "saml/remote-simpleSAMLphp"
    else:
         IDP_STRATEGY = "saml"

如注释中所述,您在每行末尾添加\。您还可以将每个 getProperty("app.auth.idp.strategy") 替换为一个变量,以便调用一次。

【讨论】:

    【解决方案4】:

    您可以使用 '\' 显式中断它,也可以通过将条件放在括号内来中断它

    if (a
        ==b
        ==c):
    

    【讨论】:

    • 你可以,但不能。请按照 D.S. Dhaliwal 基于 pep8 的回答:在or/and 上休息,无论您是否使用括号,都不要拆分测试
    猜你喜欢
    • 1970-01-01
    • 2022-12-16
    • 2018-08-18
    • 2014-04-26
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 2017-05-11
    相关资源
    最近更新 更多