Python进阶-XIII 导入模块和包 异常处理

1、模块的导入python

1)、importmysql

 1 # 测试一:money与my_module.money不冲突
 2 import my_module
 3 money=10
 4 print(my_module.money)
 5 
 6 '''
 7 执行结果:
 8 from the my_module.py
 9 1000
10 '''
11 
12 #测试二:read1与my_module.read1不冲突
13 
14 import my_module
15 def read1():
16     print('========')
17 my_module.read1()
18 
19 #测试三:执行my_module.change()操做的全局变量money仍然是my_module中的
20 #demo.py
21 import my_module
22 money=1
23 my_module.change()
24 print(money)
25 
26 '''
27 执行结果:
28 from the my_module.py
29 1
30 '''
31 
32 '''
33 执行结果:
34 from the my_module.py
35 my_module->read1->money 1000
36 '''
View Code

首次导入模块my_module时会作三件事:web

(1). 为源文件(my_module模块)建立新的名称空间,在my_module中定义的函数和方法如果使用到了global时访问的就是这个名称空间。
(2). 在新建立的命名空间中执行模块中包含的代码,见初始导入import my_module
(3). 建立名字my_module来引用该命名空间

补充:能够为模块名起别名 如:import xmlreader as reader
 1 import my_module as sm
 2 print(sm.money)
 3 # 示范用法一:
 4 # 有两中sql模块mysql和oracle,根据用户的输入,选择不一样的sql功能
 5 def sqlparse():
 6     print('from mysql sqlparse')
 7 #oracle.py
 8 def sqlparse():
 9     print('from oracle sqlparse')
10 
11 #test.py
12 db_type=input('>>: ')
13 if db_type == 'mysql':
14     import mysql as db
15 elif db_type == 'oracle':
16     import oracle as db
17 
18 db.sqlparse()
19 
20 # 示范用法二:
21 # 为已经导入的模块起别名的方式对编写可扩展的代码颇有用,假设有两个模块xmlreader.py和csvreader.py,
22 # 它们都定义了函数read_data(filename):用来从文件中读取一些数据,但采用不一样的输入格式。能够编写代码来选择性地挑选读取模块,例如
23 if file_format == 'xml':
24      import xmlreader as reader
25 elif file_format == 'csv':
26      import csvreader as reader
27 data=reader.read_date(filename)
View Code

能够在一行导入多个模块,如:sql

import sys,os,re

2)、from importjson

 

对比import my_module,会将源文件的名称空间'my_module'带到当前名称空间中,使用时必须是my_module.名字的方式
而from 语句至关于import,也会建立新的名称空间,可是将my_module中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就能够了:如
from my_module import read1,read2
样在当前位置直接使用read1和read2就行了,执行时,仍然以my_module.py文件全局名称空间
 1 #测试一:导入的函数read1,执行时仍然回到my_module.py中寻找全局变量money
 2 
 3 from my_module import read1
 4 money=1000
 5 read1()
 6 '''
 7 执行结果:
 8 from the my_module.py
 9 spam->read1->money 1000
10 '''
11 
12 #测试二:导入的函数read2,执行时须要调用read1(),仍然回到my_module.py中找read1()
13 from my_module import read2
14 def read1():
15     print('==========')
16 read2()
17 
18 '''
19 执行结果:
20 from the my_module.py
21 my_module->read2 calling read1
22 my_module->read1->money 1000
23 '''
24 
25 # 若是当前有重名read1或者read2,那么会有覆盖效果。
26 
27 # 测试三:导入的函数read1,被当前位置定义的read1覆盖掉了
28 
29 from my_module import read1
30 def read1():
31     print('==========')
32 read1()
33 '''
34 执行结果:
35 from the my_module.py
36 ==========
37 '''
38 # 须要特别强调的一点是:python中的变量赋值不是一种存储操做,而只是一种绑定关系,以下:
39 from my_module import money,read1
40 money=100  # 将当前位置的名字money绑定到了100
41 print(money)  # 打印当前的名字
42 read1()  # 读取my_module.py中的名字money,仍然为1000
43 
44 # 也支持as
45 from my_module import read1 as read
46 
47 # 也支持导入多行
48 from my_module import (read1,
49                    read2,
50                   money)
51 
52 '''
53 from the my_module.py
54 100
55 my_module->read1->money 1000
56 '''
57 
58 # from my_module import * 把my_module中全部的不是如下划线(_)开头的名字都导入到当前位置,大部分状况
59 # 下咱们的python程序不该该使用这种导入方式,由于*你不知道你导入什么名字,颇有可能会覆盖掉你以前已经定义的名字。
60 #  并且可读性极其的差,在交互式环境中导入时没有问题。
61 
62 from my_module import * #将模块my_module中全部的名字都导入到当前名称空间
63 print(money)
64 print(read1)
65 print(read2)
66 print(change)
67 
68 '''
69 执行结果:
70 from the my_module.py
71 1000
72 <function read1 at 0x1012e8158>
73 <function read2 at 0x1012e81e0>
74 <function change at 0x1012e8268>
75 '''
76 
77 # 在my_module.py中新增一行
78 __all__=['money','read1'] #这样在另一个文件中用from my_module import *就这能导入列表中规定的两个名字
79 # *若是my_module.py中的名字前加_,即_money,则from my_module import *,则_money不能被导入
View Code

 

2、包的导入api

1)、常见非web项目的包结构oracle

softapp

++binide

++++start.py函数

++conf

++++config.ini

++++my_log_settings.py

++++settings.py

++core

++++core.py

++db

++++some_db.json

++lib

++++some_lib.py

++log

++++some_log.py

建立代码

 1 import os
 2 os.makedirs('soft/bin')
 3 os.makedirs('soft/conf')
 4 os.makedirs('soft/core')
 5 os.makedirs('soft/db')
 6 os.makedirs('soft/lib')
 7 os.makedirs('soft/log')
 8 
 9 l = []
10 l.append(open('soft/__init__.py', 'w'))
11 l.append(open('soft/bin/__init__.py', 'w'))
12 l.append(open('soft/bin/start.py', 'w'))
13 l.append(open('soft/conf/__init__.py', 'w'))
14 l.append(open('soft/conf/config.ini', 'w'))
15 l.append(open('soft/conf/my_log_settings.py', 'w'))
16 l.append(open('soft/conf/settings.py', 'w'))
17 l.append(open('soft/core/__init__.py', 'w'))
18 l.append(open('soft/db/__init__.py', 'w'))
19 l.append(open('soft/lib/__init__.py', 'w'))
20 l.append(open('soft/log/__init__.py', 'w'))
21 
22 map(lambda f:f.close(), l)
View Code

 

2)、注意事项

 (1).关于包相关的导入语句也分为import和from ... import ...两种,可是不管哪一种,不管在什么位置,在导入时都必须遵循一个原则:
凡是在导入时带点的,点的左边都必须是一个包,不然非法。
   能够带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。
(2).对于导入后,在使用时就没有这种限制了,点的左边能够是包,模块,函数,类(它们均可以用点的方式调用本身的属性)。
(3).对比import item 和from item import name的应用场景:
     若是咱们想直接使用name那必须使用后者。

3)、具体使用
(1)import
咱们在与包glance同级别的文件中测试
import glance.db.models  # 虽然有报错,可是正确的!
glance.db.models.register_models('mysql')
(2)from import
须要注意的是from后import导入的模块,必须是明确的一个不能带点,不然会有语法错误,如:from a import b.c是错误语法
咱们在与包glance同级别的文件中测试
# from glance.db import models
# models.register_models('oracle')
# 还能够
# from glance.db.models import register_models
# register_models('mysql')

(3)__init__.py文件
不论是哪一种方式,只要是第一次导入包或者是包的任何其余部分,都会依次执行包下的__init__.py文件(咱们能够在每一个包的文件内都
# 打印一行内容来验证一下),这个文件能够为空,可是也能够存放一些初始化包的代码。

(4)from glance.api import *
在讲模块时,咱们已经讨论过了从一个模块内导入全部*,此处咱们研究从一个包导入全部*。 此处是想从包api中导入全部,实际上该语句只会导入包api下__init__.py文件中定义的名字,咱们能够在这个文件中定义__all___:
# x=10
# def func():
# print('from api.__init.py')
# __all__=['x','func','policy']
#此时咱们在于glance同级的文件中执行
# from glance.api import *
# 就导入__all__中的内容(versions仍然不能导入)。
# func()
# policy.get()
# versions.create_resource('mysql') #NameError: name 'versions' is not defined

(5)绝对导入和相对导入
 咱们的最顶级包glance是写给别人用的,而后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:
绝对导入:以glance做为起始(要看sys.path()中的路径是否包含该路径!)
from glance.cmd import manage
manage.main()
相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不一样目录内)
例如:咱们在glance/cmd/manage.py中想要导入glance/api/version.py
from ..api import policy
可是不能在该py文件中直接运行,要从该文件所在包之外的地方调用,才会有效果!

三、异常处理
1)、各类状况下的错误示例
1/0 ZeroDivisionError: division by zero
name NameError: name 'name' is not defined
2+'3' TypeError: unsupported operand type(s) for +: 'int' and 'str'
[][3] IndexError: list index out of range
{}['k'] KeyError: 'k'
2)、使用try捕获错误,进行处理
1)、except 捕获错误 进行处理
2)、else 若是try中的语句没有错误,执行的代码。
3)、finally 不论是否有错误,都会执行的代码
 1 try:
 2     print('1111')
 3     # 1/0
 4     print('2222')
 5     # name
 6     # 2+'3'
 7     # [][3]
 8     # {}['k']
 9     ret = int(input('number >>>'))
10     print(ret*'*')
11 except ValueError:
12     print('输入的数据类型有误')
13 except Exception:
14     print('你错了,老铁')
15 else:
16     print('没有异常的时候执行else中的代码')
17 print('===========')
18 def func():
19     try:
20         f = open('file','w')
21         ''''''
22         return True
23     except:
24         return False
25     finally:
26         print('执行finally了')
27         f.close()
28 
29 print(func())
View Code
三、注意事项
程序一旦发生错误,就从错误的位置停下来了,不在继续执行后面的内容
使用try和except就能处理异常
try是咱们须要处理的代码
except 后面跟一个错误类型 当代码发生错误且错误类型符合的时候 就会执行except中的代码
except支持多分支
有没有一个能处理全部错误的类型 : Exception
有了万能的处理机制仍然须要把能预测到的问题单独处理
单独处理的全部内容都应该写在万能异常以前
else : 没有异常的时候执行else中的代码
finally : 无论代码是否异常,都会执行
finally和return相遇的时候 依然会执行
函数里作异常处理用,不论是否异常去作一些收尾工做
ry:
    print('1111')
    # 1/0
    print('2222')
    # name
    # 2+'3'
    # [][3]
    # {}['k']
    ret = int(input('number >>>'))
    print(ret*'*')
except Exception as error:
    print('你错了,老铁',error)
相关文章
相关标签/搜索