我想编写一个Python函数来改变其中一个参数(这是一个列表,即可变).像这样的东西:
def change(array):
array.append(4)
change(array)
Run Code Online (Sandbox Code Playgroud)
我更熟悉传递值而不是Python的设置(无论你决定调用它).所以我通常会写这样的函数:
def change(array):
array.append(4)
return array
array = change(array)
Run Code Online (Sandbox Code Playgroud)
这是我的困惑.由于我可以改变参数,第二种方法似乎是多余的.但第一个感觉不对.此外,我的特定功能将有几个参数,其中只有一个会改变.第二种方法清楚地说明了哪个参数正在改变(因为它被赋值给变量).第一种方法没有给出任何指示.有会议吗?哪个更好'?谢谢.
aba*_*ert 18
Python中的约定是函数要么改变某些东西,要么返回一些东西,而不是两者.
如果两者都有用,你通常会编写两个单独的函数,其中mutator以一个活动动词change命名,而非mutator以一个分词命名changed.
几乎所有内置函数和stdlib都遵循这种模式.list.append你正在调用的方法什么都不返回.与list.sort-but 相同但sorted仅保留其参数,而是返回一个新的已排序副本.
对于某些特殊方法有一些例外(例如,__iadd__应该变异然后返回self),并且在一些情况下,显然必须有一件事变异并且返回不同的东西(例如list.pop),并且尝试使用Python作为一种特定于域的语言的库,与目标域的习语一致,比与Python的习语(例如,一些SQL查询表达式库)一致更重要.像所有公约一样,除非有充分理由不这样做,否则遵循这一惯例.
那么,为什么Python以这种方式设计呢?
嗯,首先,它会使某些错误显而易见.如果你期望一个函数是非变异的并且返回一个值,那么很明显你错了,因为你会得到一个错误AttributeError: 'NoneType' object has no attribute 'foo'.
它也具有概念意义:一个不返回任何东西的函数必须有副作用,或者为什么有人会写它?
但是事实上,Python中的每个语句都完全改变了一件事 - 几乎总是在语句中最左边的对象.在其他语言中,赋值是一个表达式,变异函数返回self,并且您可以将一大堆突变链接到一行代码中,这使得状态变化更难以一目了然,详细了解它们,或者在调试器中逐步执行它们.
当然所有这些都是一种权衡 - 它使得一些代码在Python中比在JavaScript中更冗长 - 但它是一种权衡,深深嵌入Python的设计中.
mgi*_*son 15
第一种方式:
def change(array):
array.append(4)
change(array)
Run Code Online (Sandbox Code Playgroud)
是最惯用的方式.通常,在python中,我们期望一个函数要么改变参数,要么返回1.这样做的原因是因为如果一个函数没有返回任何东西,那么它就非常清楚该函数必须具有一些副作用才能证明它的存在(例如改变输入).
另一方面,如果你以第二种方式做事:
def change(array):
array.append(4)
return array
array = change(array)
Run Code Online (Sandbox Code Playgroud)
当你没想到它时,你很容易找到一个可变对象突然改变的错误 - "但我以为change是副本"......
1从技术上讲,每个函数都返回一些东西,_something_恰好是None......
改变一个参数并返回它几乎没有意义。它不仅可能会给阅读代码的人带来混乱,而且会让您容易受到可变默认参数问题的影响。如果获得函数结果的唯一方法是通过变异参数,则为参数提供默认值是没有意义的。
您在问题中没有显示第三个选项。不要改变作为参数传递的对象,而是复制该参数并返回它。这使得它成为一个没有副作用的纯函数。
def change(array):
array_copy = array[:]
array_copy.append(4)
return array_copy
array = change(array)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7383 次 |
| 最近记录: |