Python一一模块代码编写基础

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuanyin235/article/details/83045664

模块的创建

定义模块,只要使用文本编辑器,把一些Python代码输入至文本文件中,然后以“.py”为后缀名进行保存,任何此类文件都会被自动认为是Python模块。在模块顶层指定的所有变量名都会变成其属性(与模块对象结合的变量名),并且可以导出供客户端来使用。

模块的使用

客户端执行import或from语句来使用模块,如果模块还没有加载,这两个语句就会去搜索、编译以及执行模块文件程序。主要的差别在于,import会读取整个模块,所以必须进行定义后才能读取它的变量名;from将获取(或者说是复制)模块特定的变量名

如下是两种使用区别:

比如我们一开始定义了一个module1.py模块,如下所示:

# module1.py
def printer(x):          # Module attribute
    print(x)

我们分别用import和from来使用该模块

import module1
module1.printer('hello world!')
from module1 import printer
printer('hello world!')

from语句其实只是稍稍扩展了import语句而已,它照常导入了模块文件,但是多了一个步骤,将文件中的一个或多个变量名从文件中复制了出来。

from *语句

from module1 import *
printer('hello world!')

from *形式只是多加个步骤,把模块中所有变量名复制到了进行导入的作用域之内。从根本上来说,这就是把一个模块的命名空间融入另一个模块之中;同样地,实际效果就是可以让我们少输入一些。

注意:Python3.0中,这里所述的from *语句形式只能用在一个模块文件的顶部,不能用于一个函数中。

导入只发生一次

模块会在第一次import或from时载入并执行,并且只在第一次如此。这是有意而为之的,因为该操作开销较大。在默认情况下,Python只对每个文件的每个进程做一次操作。之后的导入操作都只会指出已加载的模块对象。

如下,我们先定义simple.py模块

print('hello')
spam = 1

然后我们分别import模块两次,两次之间改变属性的值,如下所示:

import simple
print(simple.spam)

simple.spam = 2
import simple
print(simple.spam)

输出的结果如下:

hello
1
2

我们可以看到,第二次和其后的导入并不会重新执行此模块的代码,只是从Python内部模块表中取出已创建的模块对象。因此,变量spam不会再进行初始化。

import和from是赋值语句

就像def一样,import和from时可执行的语句,而不是编译期间的声明,而且它们可以嵌套在if测试中,出现在函数def之中等。

import将整个模块对象赋值给一个变量名

from将一个或多个变量名赋值给另一个模块中同名的对象

以form复制的变量名会变成对共享对象的引用。就像函数的参数,对已取出的变量名重新赋值,对于其复制之处的模块并没有影响,但是修改一个已取出的可变对象,则会影响导入的模块内的对象。如下所示:

我们先在small.py中定义如下对象:

x = 1
y = [1,2]
from small import x,y
x = 42
y[0] = 42
import small
print(small.x)
print(small.y)

运行结果:

1
[42, 2]

此处,x并不是一个共享的可变对象,但y是。导入者中的变量名y和被导入者都引用相同的列表对象,所以在其中一个地方的修改,也会影响另一个地方的这个对象。

from语句潜在的陷阱

建议:简单模块一般倾向于使用import,而不是from。多数的from语句是用于明确例举出想要的变量,而且限制在每个文件中只用一次from *形式。这样一来,任何无定义的变量名都可被认为是存在于from *所引起的模块内。

何时使用import

当你必须使用两个不同模块内定义的相同变量名的变量时,才真的必须使用import,这种情况下不能使用from。

模块命名空间

文件生成命名空间

在模块文件顶层(也就是不在函数或类的主体内)每一个赋值了的变量名都会变成该模块的属性。

        模块语句会在首次导入时执行。

        顶层的赋值语句会创建模块属性

       模块的命名空间能通过属性__dict__或dir(M)获取

       模块是一个独立的作用域(本地变量就是全局变量)

导入和作用域

函数绝对无法看见其他函数内的变量名,除非它们从物理上处于整个函数内

模块程序代码绝对无法看见其他模块内的变量名,除非明确地进行了导入

在Python中,一段程序的作用域完全由程序所处的文件中实际位置决定。作用域绝不会被函数调用或模块导入影响。

重载模块(reload)

与import和from不同的是:

      reload是Python中的内置函数,而不是语句

      传给reload的是已经存在的模块对象,而不是变量名

      reload在Python3.0中位于模块之中,并且必须导入自己

下面是一些细节:

      reload会在模块当前命名空间内执行模块文件的新代码

      文件中顶层赋值语句会使得变量名换成新值

      重载会影响所有使用import读取了模块的客户端

      重载只会对以后使用from的客户端造成影响

猜你喜欢

转载自blog.csdn.net/xuanyin235/article/details/83045664