当前位置: 首页 > news >正文

vs开发网站开发教程/百度风云榜明星

vs开发网站开发教程,百度风云榜明星,如何在12366网站上做实名认证,wordpress 修改 点击量转发自:http://blog.jobbole.com/43826/ 在之前几个月里,我教一些不了解Python的孩子来慢慢熟悉这门语言。渐渐地,我发现了一些几乎所有Python初学者都会犯的错误,所以我决定跟来跟大家分享我的建议。这个系列的每个部分都会关注不…

转发自:http://blog.jobbole.com/43826/

在之前几个月里,我教一些不了解Python的孩子来慢慢熟悉这门语言。渐渐地,我发现了一些几乎所有Python初学者都会犯的错误,所以我决定跟来跟大家分享我的建议。这个系列的每个部分都会关注不同的常见错误,描述如何产生这种错误的,并且提供解决的方法。本文是第二部分。

作用域

在这篇文章里,我们来关注作用域在Python被误用的地方。通常,当我们定义了一个全局变量(好吧,我这样说是因为讲解的需要——全局变量是不好的),我们用一个函数访问它们是能被Python理解的:

1
2
3
bar = 42
def foo():
    print bar

在这里,我们在foo函数里使用了全局变量bar,然后它也如预想的能够正常运行:

1
2
>>> foo()
42

这样做很酷。通常,我们在使用了这个特性之后就想在所有的代码里用上它。如果像以下的例子中使用的话还是能够正常运行的:

1
2
3
4
5
6
7
bar = [42]
def foo():
    bar.append(0)
foo()
>>> print bar
[42, 0]

但是,如果我们把bar变一下呢:

1
2
3
4
5
6
>>> bar = 42
... def foo():
...     bar = 0
... foo()
... print bar
42

我们可以看到foo函数运行的好好的并且没有抛出异常,但是当我们打印bar的值的时候会发现它的值仍然是42。造成这种情况的原因就是 bar=0 这行代码,它没有改变全局变量bar的值,而是创建了一个名字也叫bar的局部变量并且它的值为0。这是个很难发现的bug,这会让没有真正理解Python作用域的新手非常痛苦。为了理解Python是如何处理局部变量和全局变量的,我们来看一种更少见的,但是可能会更让人困惑的错误,我们在打印bar的值后定义一个叫bar这个局部变量:

1
2
3
4
bar = 42
def foo():
    print bar
    bar = 0

这样写应该是不会出错的,不是吗?我们在打印了值之后定义了相同名称的变量,所以这应该是不会影响的(Python毕竟是一种解释型语言),真的是这样吗?

 

出错了

这怎么可能呢?好吧,这里有两处错误。第一点就是关于Python的,作为一种解释型语言(非常酷,我们都同意这一点),是一行一行地执行的。而事实上,Python是一个声明一个声明执行的。为了让你对我想表达的意思有点感觉,赶紧打开你最爱的shell,然后输入以下代码:

1
def foo():

按回车键。正如你看到的,shell里面并没有打出任何输出而是等着让你继续函数的定义。Shell里会一直这样直到你停止定义函数。这是因为定义函数是一个声明。好吧,这是一个混合的声明,里面包含了一些其他的声明,但它仍然是一个声明。直到函数被调用,不然这个函数里的内容是不会执行的。真正执行的是一个function类型的对象被创建出来了。

这引导我们来关注第二点。再强调一下,Python的动态性和解释型的特性让我们相信当 print bar 这行被执行的时候,Python会在首先在局部作用域里寻找叫bar的变量然后再去寻找全局作用域里的。但实际上发生的是局部作用域不是完全动态的。当def 这个声明执行的时候,Python会静态地从这个函数的局部作用域里获取信息。当来到 bar=0 这行的时候(不是执行到这行代码,而是当Python解释器读到这行代码的时候),它会把’bar’这个变量加入到foo函数的局部变量列表里。当foo函数执行并且Python准备执行print bar这行的时候,它就会在局部的作用域里寻找这个变量,由于这个过程是静态的,Python知道这个变量还没有被赋值,这个变量没有值,所以抛出了异常。

你可能会问:为什么不能在声明函数的时候抛出这个异常呢?Python可以知道预先知道bar这个变量在赋值前被引用了。这个问题的答案就是Python无法知道这个局部变量bar是否被赋值了。看看下面的例子:

1
2
3
4
5
bar = 42
def foo(baz):
    if baz > 0:
        print bar
    bar = 0

Python在动态和静态之间玩了一个微妙的游戏。它唯一知道的事情就是bar是被赋值了,但它不知道在赋值前被引用这个异常是否存在直到它真的发生。好吧,老实说,它根本就不知道这个变量是否被赋值!

 

1
2
3
4
5
6
7
8
9
10
11
12
13
bar = 42
def foo():
    print bar
    if False:
        bar = 0
>>> foo()
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    foo()
  File "<pyshell#16>", line 3, in foo
    print bar
UnboundLocalError: local variable 'bar' referenced before assignment

看到上面的代码里面,虽然我们作为一种智能生物能够很清楚的知道不会给bar赋值。Python无视了那个事实而是仍然声明了bar这个局部变量。

关于这个问题我已经说了够长了。我们需要的是解决方案,我会在这里给出两个解决方法。

1
2
3
4
5
6
7
8
9
10
>>> bar = 42
... def foo():
...     global bar
...     print bar
...     bar = 0
...
... foo()
42
>>> bar
0

第一就是使用global关键字。这是不言自明的。这会让Python知道bar是一个全局变量而不是局部变量。

第二个方法,也是更推荐使用的,就是不要使用全局变量。在我的大量Python开发工作中从来没有用到global这个关键字。能知道怎么用它就行了,但最终还是要尽量避免使用它。如果你想保存在代码里至始至终用到的值的时候,把它定义为一个类的属性。用这种方法的话就完全不需要用global了,当你要用这个值的时候,通过类的属性来访问就可以了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> class Baz(object):
...     bar = 42
...
... def foo():
...     print Baz.bar  # global
...     bar = 0  # local
...     Baz.bar = 8  # global
...     print bar
...
... foo()
... print Baz.bar
42
0
8
http://www.jmfq.cn/news/5038849.html

相关文章:

  • 哈尔滨网站建设30t/学推广网络营销去哪里
  • 做网站注意/太原seo排名优化公司
  • 企业建网站费用/国产免费crm系统有哪些在线
  • 高端网站设计收费/营销推广48个方法
  • 六枝做网站/免费建立一个网站
  • java做的网站怎么转app/百度一下的网址
  • 做二手车网站怎么做的/常见的网站推广方式有哪些
  • 辽阳好的网站建设公司/个人引流推广怎么做
  • 唐河企业网站制作哪家好/seo软文是什么意思
  • 唯一做性视频的网站/360优化大师官方版
  • 两学一做网站无法做题/广告优化师工作内容
  • 做英文的小说网站/网站推广服务报价表
  • 鞍山网站建设营销/网络营销策划书范文
  • 东营中移动网站建设/网络优化报告
  • wordpress广告最后加载/杭州seo网站推广
  • 网站开发实训心得体会/网站搜索引擎优化
  • 字体设计网站有哪些/网络推广好做吗?
  • 进口彩妆做的好的网站/引流app推广软件
  • 网站打开慢/官网优化包括什么内容
  • 哪个网站做二手车抵押/seo超级外链工具
  • 网站定制建设公司/15个常见关键词
  • 网站推广的内涵/2022最新永久地域网名
  • 互联网信息服务平台入口/seo优化的主要任务包括
  • 武汉五合一网站建设/求几个微信推广平台
  • 鞍山网站制作公司/无锡网络推广平台
  • 技术支持 东莞网站建设母婴护理/外链免费发布平台
  • 手机如何登入网站服务器/360地图怎么添加商户
  • 衡水网站设计/如何优化网站首页
  • 免费建企业网站/上海百度推广客服电话
  • wordpress设置icon/企业网站的优化建议