在我看来,在python中,将要在函数中使用的变量传递给该函数并不是强制的。在
此代码:
def functionWithoutArgs():
print(theList)
theList.append('asdf')
print(theList)
theNewList = theList + ['qwer']
print(theNewList)
return theNewList
theList = ['this', 'is', 'a', 'list']
theLastList = functionWithoutArgs()
print(theLastList)
给出以下输出(没有错误或警告):
^{pr2}$我很惊讶没有提出例外。这是因为(在我看来)允许函数使用未传递给它们的变量会严重混淆该函数与其他代码的交互方式。
据我所知,函数的全部意义在于将程序分解成小部分,使它们与其余代码的交互作用得到明确定义。在
问题:
为什么python允许在未传递给函数的函数内使用变量?在
其他信息:
示例中代码过多的原因是这个线程
Use a Variable in a Function Without Passing as an Argument
其中接受的答案声称,只有当被调用的函数没有修改或重命名变量(至少据我所知),才允许使用未经赋值的变量,这是上面的代码反例。在
我知道这个问题是一个“为什么…”的问题,是一个边缘主观或基于意见的问题,但我觉得这是如此根本,必须有某种共识的论点。此外,对于许多新的python程序员来说,这也是非常有用的知识。在
这种做法使用的是在范围之外定义的“阴影名称”,通常是this is a very bad practice。许多ide和代码检查工具都会在这里报告错误或警告。在
实际上,许多动态类型化语言都允许这种行为。在我看来,这是因为,在编写函数时,我们希望能够按照我们喜欢的任何顺序来编写函数。对于像C这样将声明和定义分开的语言,我们可以确保在定义部分声明所有内容。在
但是,对于python,它没有声明名称的类型,情况就不同了。如果我们不允许来自外部范围的名称,我们突然之间就不能有相互递归和许多编程结构!在
一个完整的答案需要对整个语言如何工作进行深入的解释,这已经被记录在案-the official doc about scoping and namespaces可能是这里最好的起点。在
长话短说,在Python中,一切都是一个对象,包括函数、类和模块,函数、模块和类没有明确的名称空间。在下面的代码中:
{{{cd2>实际上是一个bar和{},如果需要一个特殊的声明来访问全局变量,那么每次函数使用另一个函数、类或模块时,都必须编写大量的样板代码,这至少是不实际的。在
好吧,重新绑定(甚至只是改变)非本地名称确实会导致很多问题——wrt/readability(对代码进行推理的能力)、可测试性等等,但是wrt/concurrency和reentrancy,应该尽量避免。在
但从一个实际的视角来看,你很难避免至少有只读的全局变量(符号常量、其他函数、类、模块等),有时,您还需要至少几个函数,它们确实会改变/重新绑定全局名称(例如,考虑应用程序设置)——这里的要点是,这些函数只应在应用程序启动时调用,以定义符号常量等
相关问题 更多 >
编程相关推荐