我编写了一个“基于链”的Python API(类似于jQuery)。所以我可以写:
myObject.doStuff().doMoreStuf().goRed().goBlue().die()
问题是我还没有找到一种方法来保持语法清理长链。在JavaScript中我可以简单地做
myOjbect
.doStuf()
.doMoreStuf()
.goRed()
.goBlue()
.die()
但Python有缩进限制......
答案 0 :(得分:22)
实际上PEP8说:
长线可以 通过在括号中包装表达式来分解多行。这些 应优先使用反斜杠进行续行。 确保适当缩进续行。
所以我想你的代码应该是这样的:
(
myOjbect
.doStuf()
.doMoreStuf()
.goRed()
.goBlue()
.die()
)
根据语法判断,每种方法调用返回的值有两种选择:
die()
,不需要,因为它的结果没有被使用)返回修改后的实例(调用它的同一个实例)。die()
不需要这样做)返回调用它的实例的 copy 。在第一种情况(返回相同实例时)时,将较长行拆分为多个语句的解决方案是:
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中非常常用(如果有的话)。一种选择是使用看起来像
的APImyObject.do(
'Stuff',
'MoreStuff',
'Red',
'Blue',
'die',
)
虽然如果你给我们一个真实的例子,你可能会得到更多相关的建议 - 很难猜出这里有什么样的操作。也许其中一些应该合并,或放在__init__
中(例如,可以通过将可选参数传递给__init__
来设置颜色。)