在Python中使用样式化长链

时间:2012-01-11 11:29:52

标签: python

我编写了一个“基于链”的Python API(类似于jQuery)。所以我可以写:

myObject.doStuff().doMoreStuf().goRed().goBlue().die()

问题是我还没有找到一种方法来保持语法清理长链。在JavaScript中我可以简单地做

myOjbect
   .doStuf()
   .doMoreStuf()
   .goRed()
   .goBlue()
   .die()

但Python有缩进限制......

5 个答案:

答案 0 :(得分:22)

符合PEP8标准的解决方案:格式化行

实际上PEP8说:

  

长线可以       通过在括号中包装表达式来分解多行。这些       应优先使用反斜杠进行续行。       确保适当缩进续行。

所以我想你的代码应该是这样的:

(
    myOjbect
    .doStuf()
    .doMoreStuf()
    .goRed()
    .goBlue()
    .die()
)

替代解决方案:分成单独的陈述

根据语法判断,每种方法调用返回的值有两种选择:

  1. 每个方法(可能除了die(),不需要,因为它的结果没有被使用)返回修改后的实例(调用它的同一个实例)。
  2. 每个方法(仍然,die()不需要这样做)返回调用它的实例的 copy
  3. 可变对象的解决方案(方法返回原始实例)

    第一种情况(返回相同实例时)时,将较长行拆分为多个语句的解决方案是:

    myObject.doStuf()
    myObject.doMoreStuf()
    myObject.goRed()
    myObject.goBlue()
    myObject.die()
    

    真实世界的例子涉及可变对象:

    my_stuff = []
    my_stuff.append('laptop')  # my_stuff == ['laptop']
    my_stuff.append('jacket')  # my_stuff == ['laptop', 'jacket']
    my_stuff.append('apple')  # my_stuff == ['laptop', 'jacket', 'apple']
    

    (虽然list.append()不会返回任何内容,只是为了保持一致性并明确声明它是可变的)

    不可变对象的解决方案(方法返回修改后的副本)

    第二种情况(返回副本时),执行类似操作的解决方案是:

    myObject = myObject.doStuf()
    myObject = myObject.doMoreStuf()
    myObject = myObject.goRed()
    myObject = myObject.goBlue()
    myObject.die()
    

    真实世界的例子涉及不可变对象:

    name = '-Tadek-'
    name = name.strip('-')  # name == 'Tadek'
    name = name.lower()  # name == 'tadek'
    name = name.replace('k', 'ck')  # name == 'tadeck'
    

答案 1 :(得分:8)

myOjbect \
   .doStuf() \
   .doMoreStuf() \
   .goRed() \
   .goBlue() \
   .die()

(我为myObject感到遗憾。这听起来很痛苦。)

答案 2 :(得分:4)

虽然我不会称之为“干净”,但可以在括号内打破:

myOjbect.doStuf(
   ).doMoreStuf(arg1, arg2
   ).goRed(
   ).goBlue(
   ).die()

口味各不相同,所以我把它作为完整性的答案。

答案 3 :(得分:3)

我发现让“链条”看起来不错的一个好方法就是简单地输入一下:

obj = myObject.doStuff()
obj = obj.doMoreStuf()
obj = obj.goRed()
obj = obj.goBlue()
obj = obj.die()

或更好:使用有意义的名称,使代码更加明显。

obj = myObject.doStuff().doMoreStuf()
colored_object = obj.goRed().goBlue()
colored_object.die()

答案 4 :(得分:-2)

我不认为这样的链接方法在python中非常常用(如果有的话)。一种选择是使用看起来像

的API
myObject.do(
    'Stuff',
    'MoreStuff',
    'Red',
    'Blue',
    'die',
    )

虽然如果你给我们一个真实的例子,你可能会得到更多相关的建议 - 很难猜出这里有什么样的操作。也许其中一些应该合并,或放在__init__中(例如,可以通过将可选参数传递给__init__来设置颜色。)