Python进阶-XIII 导入模块和包 异常处理
一、模块的导入
1)、import
# 测试一:money与my_module.money不冲突
import my_module
money=10
print(my_module.money) '''
执行结果:
from the my_module.py
1000
''' #测试二:read1与my_module.read1不冲突 import my_module
def read1():
print('========')
my_module.read1() #测试三:执行my_module.change()操作的全局变量money仍然是my_module中的
#demo.py
import my_module
money=1
my_module.change()
print(money) '''
执行结果:
from the my_module.py
1
''' '''
执行结果:
from the my_module.py
my_module->read1->money 1000
'''
首次导入模块my_module时会做三件事:
(1). 为源文件(my_module模块)创建新的名称空间,在my_module中定义的函数和方法若是使用到了global时访问的就是这个名称空间。
(2). 在新创建的命名空间中执行模块中包含的代码,见初始导入import my_module
(3). 创建名字my_module来引用该命名空间 补充:可以为模块名起别名 如:import xmlreader as reader
import my_module as sm
print(sm.money)
# 示范用法一:
# 有两中sql模块mysql和oracle,根据用户的输入,选择不同的sql功能
def sqlparse():
print('from mysql sqlparse')
#oracle.py
def sqlparse():
print('from oracle sqlparse') #test.py
db_type=input('>>: ')
if db_type == 'mysql':
import mysql as db
elif db_type == 'oracle':
import oracle as db db.sqlparse() # 示范用法二:
# 为已经导入的模块起别名的方式对编写可扩展的代码很有用,假设有两个模块xmlreader.py和csvreader.py,
# 它们都定义了函数read_data(filename):用来从文件中读取一些数据,但采用不同的输入格式。可以编写代码来选择性地挑选读取模块,例如
if file_format == 'xml':
import xmlreader as reader
elif file_format == 'csv':
import csvreader as reader
data=reader.read_date(filename)
可以在一行导入多个模块,如:
import sys,os,re
2)、from import
对比import my_module,会将源文件的名称空间'my_module'带到当前名称空间中,使用时必须是my_module.名字的方式
而from 语句相当于import,也会创建新的名称空间,但是将my_module中的名字直接导入到当前的名称空间中,在当前名称空间中,直接使用名字就可以了:如
from my_module import read1,read2
样在当前位置直接使用read1和read2就好了,执行时,仍然以my_module.py文件全局名称空间
#测试一:导入的函数read1,执行时仍然回到my_module.py中寻找全局变量money from my_module import read1
money=1000
read1()
'''
执行结果:
from the my_module.py
spam->read1->money 1000
''' #测试二:导入的函数read2,执行时需要调用read1(),仍然回到my_module.py中找read1()
from my_module import read2
def read1():
print('==========')
read2() '''
执行结果:
from the my_module.py
my_module->read2 calling read1
my_module->read1->money 1000
''' # 如果当前有重名read1或者read2,那么会有覆盖效果。 # 测试三:导入的函数read1,被当前位置定义的read1覆盖掉了 from my_module import read1
def read1():
print('==========')
read1()
'''
执行结果:
from the my_module.py
==========
'''
# 需要特别强调的一点是:python中的变量赋值不是一种存储操作,而只是一种绑定关系,如下:
from my_module import money,read1
money=100 # 将当前位置的名字money绑定到了100
print(money) # 打印当前的名字
read1() # 读取my_module.py中的名字money,仍然为1000 # 也支持as
from my_module import read1 as read # 也支持导入多行
from my_module import (read1,
read2,
money) '''
from the my_module.py
100
my_module->read1->money 1000
''' # from my_module import * 把my_module中所有的不是以下划线(_)开头的名字都导入到当前位置,大部分情况
# 下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。
# 而且可读性极其的差,在交互式环境中导入时没有问题。 from my_module import * #将模块my_module中所有的名字都导入到当前名称空间
print(money)
print(read1)
print(read2)
print(change) '''
执行结果:
from the my_module.py
1000
<function read1 at 0x1012e8158>
<function read2 at 0x1012e81e0>
<function change at 0x1012e8268>
''' # 在my_module.py中新增一行
__all__=['money','read1'] #这样在另外一个文件中用from my_module import *就这能导入列表中规定的两个名字
# *如果my_module.py中的名字前加_,即_money,则from my_module import *,则_money不能被导入
二、包的导入
1)、常见非web项目的包结构
soft
++bin
++++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
创建代码
import os
os.makedirs('soft/bin')
os.makedirs('soft/conf')
os.makedirs('soft/core')
os.makedirs('soft/db')
os.makedirs('soft/lib')
os.makedirs('soft/log') l = []
l.append(open('soft/__init__.py', 'w'))
l.append(open('soft/bin/__init__.py', 'w'))
l.append(open('soft/bin/start.py', 'w'))
l.append(open('soft/conf/__init__.py', 'w'))
l.append(open('soft/conf/config.ini', 'w'))
l.append(open('soft/conf/my_log_settings.py', 'w'))
l.append(open('soft/conf/settings.py', 'w'))
l.append(open('soft/core/__init__.py', 'w'))
l.append(open('soft/db/__init__.py', 'w'))
l.append(open('soft/lib/__init__.py', 'w'))
l.append(open('soft/log/__init__.py', 'w')) map(lambda f:f.close(), l)
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文件中直接运行,要从该文件所在包以外的地方调用,才会有效果! 3、异常处理
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 不管是否有错误,都会执行的代码
try:
print('')
# 1/0
print('')
# name
# 2+'3'
# [][3]
# {}['k']
ret = int(input('number >>>'))
print(ret*'*')
except ValueError:
print('输入的数据类型有误')
except Exception:
print('你错了,老铁')
else:
print('没有异常的时候执行else中的代码')
print('===========')
def func():
try:
f = open('file','w')
''''''
return True
except:
return False
finally:
print('执行finally了')
f.close() print(func())
3、注意事项
程序一旦发生错误,就从错误的位置停下来了,不在继续执行后面的内容
使用try和except就能处理异常
try是我们需要处理的代码
except 后面跟一个错误类型 当代码发生错误且错误类型符合的时候 就会执行except中的代码
except支持多分支
有没有一个能处理所有错误的类型 : Exception
有了万能的处理机制仍然需要把能预测到的问题单独处理
单独处理的所有内容都应该写在万能异常之前
else : 没有异常的时候执行else中的代码
finally : 不管代码是否异常,都会执行
finally和return相遇的时候 依然会执行
函数里做异常处理用,不管是否异常去做一些收尾工作
ry:
print('')
# 1/0
print('')
# name
# 2+'3'
# [][3]
# {}['k']
ret = int(input('number >>>'))
print(ret*'*')
except Exception as error:
print('你错了,老铁',error)
Python进阶-XIII 导入模块和包 异常处理的更多相关文章
- Python 3基础教程20-Python中导入模块和包
本文介绍Python中导入模块和包 #目录: # 导入模块和包--- # | # 上级包.上级模块.导入模块和包的init模块----- # | # 同级包.同级模块.上级包的init模块.test模 ...
- python(33)- 模块与包
一 模块 1 什么是模块? 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 2 为何要使用模块? 如果你退出python解释器然后重新进入,那么你之前定义的函 ...
- Python 入门基础13 --模块与包
本节内容: 一.模块及使用 1.模块及使用 2.起别名.from导入 3.自执行与模块 二.包的使用 2.1 包中模块的使用:import 2.2 包的嵌套 2.3 包中模块的使用:from ...i ...
- python中动态导入模块
当导入的模块不存在时,就会报ImportError错误,为了避免这种错误可以备选其他的模块或者希望优先使用某个模块或包,可以使用try...except...导入模块或包的方式. 例如: Python ...
- python三种导入模块的方法
做为python初学者,有时候搞不清楚导入模块的作用. 直接导入模块 通常模块为一个文件,直接使用import来导入就好了.可以作为module的文件类型有".py"." ...
- Python importlib(动态导入模块)
使用 Python importlib(动态导入模块) 可以将字符串型的模块名导入 示例: import importlib module = 'module name' # 字符串型模块名 test ...
- Python import语句导入模块语法[转]
Python import语句导入模块语法 社区推荐:掘金是国内最活跃的技术社区,我们每日有优质Python开发实例分享,海量python开源库推送.来掘金,和更多懂技术的小伙伴交流. pytho ...
- selenium + python自动化测试unittest框架学习(四)python导入模块及包知识点
在写脚本的时候,发现导入某些模块,经常报错提示导入模块失败,这里来恶补下python导入模块的知识点. 1.模块导入时文件查找顺序 在脚本中,import xxx模块时的具体步骤: (1)新建一个mo ...
- python入门20 导入模块(引包)
1 引包: import module 或 import module.module1 或 from module import module1,module2...等 2 import xx ...
随机推荐
- SpringCloud微服务常见组件理解
概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...
- 字节跳动笔试题:1. 小于N的质数数量;2. 逆时针二维数组;3. 判断a+b>c
1. 小于N的质数数量 import java.util.Scanner; /** * 计算小于N的质数数量 * @author Turing * */ public class Main4 { pu ...
- .NET使用Bogus生成大量随机数据(转载)
原文地址:https://www.cnblogs.com/sdflysha/p/20190821-generate-lorem-data.html 在演示Demo.数据库脱敏.性能测试中,有时需要生成 ...
- java基础之----java常见异常及代码示例
概述 java中有两种错误类型,一个是Exception,一个是Error,都在java.lang包下,一般来说程序中的try...catch捕获的是Exception类型的异常,而Error类型的错 ...
- 【shell脚本】批量修改扩展名===modifyExtension.sh
前提:需切换到需要批量修改扩展名的目录下,运行脚本 [root@VM_0_10_centos shellScript]# cat modifyExtension.sh #!/bin/bash # 编写 ...
- 【前端知识体系-JS相关】组件化和React
1. 说一下使用jQuery和使用框架的区别? 数据和视图的分离,(jQuery数据和视图混在一起,代码耦合)-------开放封闭原则 以数据驱动视图(只关注数据变化,DOM操作被封装) 2.说一下 ...
- jquery实现移动端页面加载后,向上滚动指定距离无效引起的探索
效果如下,页面加载完后向上滚动一段距离 最近一同事询问用jquery为何无法实现上面效果,查看代码后发现代码并没写错, 也正确引入了zepto.js,也不是版本问题(因为是移动端项目,出于性能和需 ...
- UVA 10790 How Many Points of Intersection? 组合数学
We have two rows. There are a dots on the top row and b dots on the bottom row. We draw line segment ...
- python 自定义Iterator对象
from collections.abc import Iterator class Company(object): def __init__(self, employee_list): self. ...
- Spring Cloud Hystrix Dashboard熔断器-Turbine集群监控(六)
序言 上一篇说啦hystrix的使用方法与配置还有工作流程及为何存在,我去,上一篇这么屌,去看看吧,没这么屌的话,我贴的有官方文档,好好仔细看看 hystrix除啦基本的熔断器功能之外,还可以对接口的 ...