模块之命名空间,,


  Carter提到的内容与命名空间(namespace)概念有关。这个话题有点复杂,不过确实需要知道,所以现在就来讨论这个概念。

  与孩子一起学编程-python教程

  什么是命名空间

  假设在你们学校,你在Morton老师的班里,班里有个学生名叫Shawn.现在Wheeler老师教的那个班也有一个名叫Shawn的学生,如果你在自己的班里说“Shawn有一个新书包”时,你们班的所有人都会知道(或者至少他们会认为),你指的是你们班的Shawn,如果你想说另外那个班的Shawn就会说“Wheeler老师班里的Shawn”或者“另外那个Shawn”或者其他类似的说法。

  你们班里只有一个Shawn,所以你说Shawn时,同班的同学就会知道你说的是哪个人。换种说法来讲,在你们班的这个空间里,只有一个名字Shawn,你们班就是你的命名空间,在这个命名空间里只有一个Shawn,所以不会有混淆。

  与孩子一起学编程-python教程

  现在,如果校长必须通过学校的广播系统把Shawn叫到办公室,她不会说“请Shawn办公室来一趟”,如果她这样做,两个Shawn都会出现在他的办公室,对于使用广播系统的校长来说,命名空间是整个学校,这说明,学校的每一个人都会听到这个名字,而不只是一个班的同学。所以她必须更明确地指出她指的是哪一个Shawn,她必须这样说,“请Morton老师班里的Shawn到办公室来一趟”

  与孩子一起学编程-python教程

  校长还可以用另一种方法找Shawn,就是走到你们班门口说:“Shawn,请跟我来。”这里只有一个Shawn听到,所以校长能找真正要找的那个Shawn,在这种情况下,命名空间就只是一个教室,而不是整个学校。

  与孩子一起学编程-python教程

  一般来讲,程序员把较小的命名空间(比如你的教室)称作局部命名空间,而较大的命名空间(如整个学校)称为全局命名空间。

  导入命名空间

  与孩子一起学编程-python教程

  下面假设你们学校(John Young)根本没有一个名叫Fred的人。如果校长通过广播系统想找到Fred,她肯定找不到这个人,现在假设与你们学校同在一条街上的另一个学校(Stephen Leacock学校)正在进行部分校舍维修,这个学校把一个班级临时搬到你们学校的活动房里上课,在这个班里,恰好有一个学生名叫Fred,不过这个活动房还没有连上广播系统。如果校长找到Fred,肯定还是找不到。但是,如果她把这个新的活动房连入广播系统,然后再找Fred,就会找到Stephen Leacock学校的Fred。

  连接另一个学校的活动房屋,这在Python中就像导入一个模块,导入了模块,就可能访问这个模块中的所有名字,包括所有变量、函数以及对象。

  导入模块的含义与导入一个命名空间是一样的。导入模块时,就导入了命名空间。

  导入命名空间(模块)有两种方法,可以这样做:import stephenLeacock

  如果这样做,StephenLeacock仍然是一个单独的命名空间。你可以访问这个命名空间,但是在使用之前必须明确地指定想要哪一个命名空间,所以校长必须这样做:

  call_to_office(stephenleacock.Fred)

  如果校长想找到Fred,除了名字(Fred)外,她还必须给出命名空间(StephenLeacock)。在前面的温度转换程序中就是这样做的。

  为了让这个程序正常工作,我们写了这样一行代码:

  这里指定了命名空间(my_module)以及函数名(c_to_f)。

  导入命名空间的另一种方法是:from StephenLeacock import fred

  如果校长这样做,会把StephenLeacock的名字Fred包含到她的命名空间中,现在就可以这样找到Fred:call_to_office(Fred)

  因为Fred现在就在校长的命名空间里,所以她不必要再去StephenLeacock命名空间找Fred。

  在这个例子中,校长只是从StephenLeacock把名字Fred导入她的局部命名空间中,如果她想导入所有人,可以这样做:from StephenLeacock import *

  在这里,星号(*)表示全部,不过她必须当心,如果StephenLeacock学校与John Young学校有同名的学生就会出现混乱了。

  太难了

  到目前为止,你可能对命名空间的概念还是不太清楚,不用担心,通过完成后面几章的例子你会琥来越明白。后面需要导入模块时,我都会清楚地解释要做什么。

评论关闭