我有几次使用Python,我发现了“pythonic”编码方式。 我在代码中使用了很多元组,其中大多数都是极坐标或笛卡尔坐标。
我发现自己在写这个:
window.set_pos([18,8])
而不是:
window.set_pos((18,8))
摆脱我发现难以阅读的双重括号。
似乎python自动进行从列表到元组的类型转换,因为我的代码正常工作。
但它是一种很好的编码方式吗? 您是否有任何可用于编写可读代码的演示提示?
提前感谢您的答案。
答案 0 :(得分:25)
我会小心翼翼地决定避免使用各种列表来支持列表。你曾经使用过dis模块吗?当你制作一个列表并制作一个元组时,观察Python在字节码级别所做的事情:
>>> def f():
... x = [1,2,3,4,5,6,7]
... return x
...
>>> def g():
... x = (1,2,3,4,5,6,7)
... return x
...
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 1 (1)
3 LOAD_CONST 2 (2)
6 LOAD_CONST 3 (3)
9 LOAD_CONST 4 (4)
12 LOAD_CONST 5 (5)
15 LOAD_CONST 6 (6)
18 LOAD_CONST 7 (7)
21 BUILD_LIST 7
24 STORE_FAST 0 (x)
3 27 LOAD_FAST 0 (x)
30 RETURN_VALUE
>>>
>>>
>>> dis.dis(g)
2 0 LOAD_CONST 8 ((1, 2, 3, 4, 5, 6, 7))
3 STORE_FAST 0 (x)
3 6 LOAD_FAST 0 (x)
9 RETURN_VALUE
虽然它可能永远不会成为GUI应用程序中的问题(正如您的示例所示),但出于性能原因,您可能需要小心在代码中的任何位置执行此操作。
答案 1 :(得分:12)
你说
似乎python自动进行从列表到元组的类型转换
这是值得怀疑的。由于列表和元组都是sequence types,因此它们都实现了许多相同的行为,并且您使用的任何GUI库都不需要任何仅列表行为。
在许多情况下,这样做可能很好,但请注意,列表确实比元组占用更多空间:
>>> sys.getsizeof((1, 2))
72
>>> sys.getsizeof([1, 2])
88
在某些事情上可能比元组慢:
>>> lst, tup = [1, 2], (1, 2)
>>> def unpack(x):
... a, b = x
...
>>> %timeit unpack(tup)
10000000 loops, best of 3: 163 ns per loop
>>> %timeit unpack(lst)
10000000 loops, best of 3: 172 ns per loop
这些非常小差异在你达到更大规模之前无关紧要 - 比如数十亿次电话 - 所以权衡可能是值得的它
但是,我并不认为人们经常这样做。这似乎是一个很好的可读性技巧,但在某些情况下可能会产生意想不到的后果。例如,如果您稍后要再次使用列表,那么您必须注意不要在函数内部修改它。最后,正如J.F. Sebastian正确指出的那样,元组和列表倾向于意味着稍微不同的东西;以非常规方式使用它们可能会否定您寻求的可读性提升。
答案 2 :(得分:8)
我严重怀疑元组与列表在你的情况下在性能上有显着差异。除非您的分析师这样说,否则不要进行微观优化。可读性是一个优先事项。
list
和tuple
都是sequence types。
语义元组可能更受欢迎(参见Tuples have structure, lists have order)。位置是具有x,y属性的单个对象。
在这种情况下,视觉列表可能更容易阅读。
无论你选择什么,只要保持一致。
检查window
是否支持以下内容:
window.pos = 18, 8
实现它的一种可能方法是将pos
设为property并将set_pos()
绑定为设置者。
答案 3 :(得分:4)
IMO使用(18,8)
而不是[18,8]
的唯一好处是元组对象是不可变的,你可以确定它不会在它传递的函数内被更改,而{{1可以很容易地改变。
答案 4 :(得分:4)
Python没有进行从列表到元组的任何自动转换,除非set_pos方法明确地这样做。元组和列表具有非常相似的协议,因此它们在该协议中往往是可互换的。你可能仍然会破坏一些东西,特别是因为元组是一个可以被散列的不可变元素,而一个列表则不是。
要回答您的问题,请写下
window.set_pos( (18,18) )
适当的空间可以创造出具有编码风格的奇迹。
答案 5 :(得分:0)
如果你想强调你的参数是一个元组的事实,你可以明确地转换它:
window.set_pot(tuple([18, 18]))