python导入自定义模块_Python入门之四十一:创建与导入自定义模块和包

Python入门之四十一:创建与导入自定义模块和包

20180712120049_749.jpg

1年前

阅读 1919

评论 0

喜欢 0

### 一、导入同级目录文件

如果需要引入同级目录下的文件,则可以采用`import`一个模块的形式,即可调用。

考虑同一目录下的两个python文件,`test.py` 需要调用`support.py` 中的函数,目录结构如下:

```

demo

|-- test.py

|-- support.py

```

`support.py` 中的代码如下:

```python

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

' a test module '

__author__ = '小黄牛'

def test(param):

print('您好:', param)

```

`test.py` 调用的代码如下:

```python

#!/usr/bin/env

# -*- coding: UTF-8 -*-

# 导入模块

import support

# 现在可以调用模块里包含的函数了

support.test('小黄牛')

```

上面的`support.py`代码中,

第1行和第2行是标准注释,

第1行注释可以让这个`support.py`文件直接在`Unix/Linux/Mac`上运行,

第2行注释表示`.py`文件本身使用标准`UTF-8`编码;

第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;

第6行使用`__author__`变量把作者写进去,这样当你公开源代码后别人就可以瞻仰你的大名;

以上就是Python模块的标准文件模板,当然也可以全部删掉不写,但是,按标准办事肯定没错。

后面开始就是真正的代码部分。

这种自定义模块的写法,一般是用于解释器模式下调用的,如果我们需要让模块支持命令行模式传递参数,就需要使用到系统自带的`sys`模块,下面我们将`support.py`文件修改为以下代码:

```python

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

' a test module '

__author__ = '小黄牛'

# 导入系统的sys模块

import sys

def test(param='小黄牛'):

# 获取系统命令行参数

args = sys.argv

print(args)

# 打印自定义参数

print(param)

if __name__=='__main__':

test()

```

导入`sys`模块后,我们就有了变量`sys`指向该模块,利用`sys`这个变量,就可以访问`sys`模块的所有功能。

`sys`模块有一个`argv`变量,用`list`存储了命令行的所有参数。

`argv`至少有一个元素,因为第一个参数永远是该`.py`文件的完整路径,例如:

运行`python3 test.py`获得的`sys.argv`就是`['完整路径/test.py']`;

运行`python3 test.py JunHao`获得的`sys.argv`就是`['完整路径/test.py', 'JunHao']`。

最后,注意到这两行代码:

```python

if __name__=='__main__':

test()

```

当我们在命令行运行`support`模块文件时,Python解释器把一个特殊变量`__name__`置为`__main__`,而如果在其他地方导入该`support`模块时,`if`判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。

### 二、导入子目录文件

如果需要引入子目录下的文件,则可以采用`import`一个包的形式,将子目录封装成包,即可调用。

考虑一个在 `functions` 目录下的 `run1.py`、`run2.py`、`__init__.py` 文件,`test.py` 为测试调用包的代码,目录结构如下:

```

test.py

functions

|-- __init__.py

|-- run1.py

|-- run2.py

```

注意:`__init__.py`可以是空文件。

`test.py` 调用代码如下:

```python

#!/usr/bin/env

# -*- coding: UTF-8 -*-

# 导入模块包

# 引入 /functions/run1.py 里的 run1()方法

from functions.run1 import run1

from functions.run2 import run2

run1()

run2()

```

当然,也可以这样使用:

```python

#!/usr/bin/env

# -*- coding: UTF-8 -*-

# 导入模块包

import function.run1

import function.run2

functions.run1.run1()

functions.run2.run2()

```

`run1.py` 代码如下:

```python

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

' a test module '

__author__ = '小黄牛'

def run1():

print('run1 Hello!')

```

`run2.py` 代码如下:

```python

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

' a test module '

__author__ = '小黄牛'

def run2():

print('run2 Hello!')

```

### 三、作用域

在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。

在Python中,是通过`_`前缀来实现的。

正常的函数和变量名是公开的(public),可以被直接引用,比如:`abc`,`x123`,`PI`等;

类似`__xxx__`这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的`__author__`,`__name__`就是特殊变量,

`run`模块定义的文档注释也可以用特殊变量`__doc__`访问,我们自己的变量一般不要用这种变量名;

类似`_xxx`和`__xxx`这样的函数或变量就是非公开的(private),不应该被直接引用,比如`_abc`,`__abc`等;

之所以我们说,`private`函数和变量“不应该”被直接引用,而不是“不能”被直接引用,是因为Python并没有一种方法可以完全限制访问`private`函数或变量,但是,从编程习惯上不应该引用`private`函数或变量。

`private`函数或变量不应该被别人引用,那它们有什么用呢?

请看例子,先修改`run1.py`中的代码:

```python

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

' a test module '

__author__ = '小黄牛'

def _private_1(name):

return 'Hello, %s' % name

def _private_2(name):

return 'Hi, %s' % name

def greeting(name):

if len(name) > 3:

return _private_1(name)

else:

return _private_2(name)

```

再修改`test.py`中的代码,然后运行:

```python

#!/usr/bin/env

# -*- coding: UTF-8 -*-

# 导入模块包

import function.run1

import function.run2

print(function.run1.greeting('小黄牛'))

function.run2.run2()

```

我们在模块里公开`greeting()`函数,而把内部逻辑用`private`函数隐藏起来了,这样,调用`greeting()`函数不用关心内部的`private`函数细节,这也是一种非常有用的代码封装和抽象的方法,即:

外部不需要引用的函数全部定义成`private`,只有外部需要引用的函数才定义为`public`。

© 著作权归作者所有

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值