您想了解有关Python范围的所有内容,但很尴尬地问

预期“ Python开发人员”课程将开始一个新线程,因此我们决定讨论Python范围。这是怎么回事?-阅读以下材料。




今天,我们将讨论重要的理论基础,这些基础理论必须得到理解和记住,才能编写出能干,易读且美观的代码。我们将讨论变量的范围。本文不仅对初学者有用,对于那些从另一种语言进入Python并想了解其机制的经验丰富的程序员也将是有用的。

范围决定了我们可以在程序的哪个部分使用特定变量,以及从哪个“变量”中隐藏该变量。了解如何仅使用我们需要的那些值和变量以及语言解释器的行为非常重要。我们还将看到如何规避范围对具有变量的操作的限制。在Python中,范围多达3个:

  • 本地
  • 全球
  • 非本地

最后一个非本地范围是在Python 3中添加的。

通常,我们在谈论函数时就谈到了范围。通过他们的例子,我们将考虑变量的工作范围。

当地范围


考虑一个some_list按元素显示列表元素的函数

def print_list(some_list):
    for element in some_list:
        print(element)

这里elementsome_list是局部变量,仅在函数内部可见,并且不能与在函数运行期间分配给它们的值一起在函数外部使用。也就是说,如果我们调用程序的主体,则会print(element)收到错误消息:

NameError: name 'element' is not defined


现在,我们将执行以下操作:

def print_list(some_list):
    for element in some_list:
        print(element) 

element = 'q'
print_list([1, 2, 3])
print(element) 


我们得到:

1
2
3
q

这里element函数内部的变量和函数外部具有相同名称的变量是两个不同的变量,它们的值不交叉也不交换。它们被称为相同,但是引用内存中的不同对象。此外,只要函数执行完毕,函数内部的名为element的变量就会存在。但是要小心,以使局部变量和全局变量具有相同的名称,现在我将说明原因:

def print_list(some_list):
    for element in sudden_list:
        print(element) 

sudden_list = [0, 0, 0]
print_list([1, 2, 3])

结果:

0
0
0

请注意,口译员并未向我们指出错误。所有这些都是因为它 sudden_list在全局范围内,也就是说,print_list我们可以从函数内部访问它,因为从内部您可以看到外部正在发生的事情。由于这种工作机制,请尝试在函数内部命名局部变量,而不是在全局范围内调用变量。

在这里谈论常量很重要。 Python解释器所谓的变量没有什么区别,因此上面的代码最好重写如下:

SUDDEN_LIST = [0, 0, 0]

def print_list(some_list):
    for element in SUDDEN_LIST:
        print(element) 

print_list([1, 2, 3]) 

现在一切就绪。问题是,在Python中,您不能以某种方式严格地将常量定义为不应修改的对象。因此,使用变量名称(以大写字母表示)的值的方式仅取决于您的良心。另一个问题是,通过这种方式,记录的变量将使任何读取您的代码的人都清楚该变量在任何地方都不会更改。或者至少不应该。

全球范围


Python有一个关键字global,允许您从函数中更改全局变量的值。它写在变量名之前,该变量名将被视为函数内部的全局变量。从示例中可以看到,现在变量的值正在candy增加,请注意,我们没有将其作为函数的参数传递get_candy()

candy = 5

def get_candy():
    global candy 
    candy += 1
    print('  {} .'.format(candy))
    
get_candy()
get_candy()
print(candy)


结果,我们得到:


	  6 .
  7 .
7


但是,从函数内更改全局变量的值不是最佳实践,最好不要这样做,因为这样做不会提高代码的可读性。函数内部发生的事件越小,取决于全局范围,则越好。

hack:为了避免遭受变量命名的麻烦,您可以将主程序代码放入一个函数中main(),然后将在该函数内部声明的所有变量都将保留在本地且不会破坏全局范围,从而增加了发生错误的可能性。

非本地范围


这个概念与关键字一起出现在Python 3中nonlocal他的写作逻辑与乔布斯的逻辑差不多global但是,nonlocal有一个功能。Nonlocal当我们想让解释器理解嵌套函数的某个变量不是局部变量,但在一般意义上来说不是全局变量时,它最常用于嵌套函数。

def get_candy():
    candy = 5
    def increment_candy(): 
        nonlocal candy
        candy += 1
        return candy
    return increment_candy
    
result = get_candy()()
print(' {} .'.format(result))

结果:

 6 .

对您来说,决定自己有多有用。您可以在此处找到更多示例

作为结论,可以制定一些规则:

  1. 在函数内部是可见的变量,这些变量已在函数内部和外部进行了定义。内部定义的变量是局部的,外部是全局的。
  2. 在函数外部,在函数内部定义的变量均不可见。
  3. , global.
  4. nonlocal , , .

就这样,我希望该材料对您有用,并且至少使您对范围在Python中的工作方式有了一点了解。处理完作用域后,您将在创建漂亮且可读的代码的方式上与众不同。

我还想邀请所有人参加OTUS 免费网络研讨会,我们在其中研究Python中的类型注释之类的工具:讨论许多人低估它的原因,考虑军事实践中类型注释可以保存或保存情况的许多示例。让我们讨论一下如何以及何时在项目上实施类型检查

All Articles