1,什么是包?
把解决一类问题的模块放在同一个文件夹里-----包
2,包是一种通过使用‘.模块名’来组织python模块名称空间的方式。
1. 无论是import形式还是from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法
2. 包是目录级的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)
3. import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
3,强调:
1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
2. 创建包的目的不是为了运行,而是被导入使用,包只是模块的一种形式而已,包即模块
4,注意事项
1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。
2.对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
3.对比import item 和from item import name的应用场景: 如果我们想直接使用name那必须使用后者。
glance/ .py │ ├── policy.py│ └── versions.py
├── cmd
<span >#<span >Subpackage for cmd<span >
│ ├── <span >init<span >.py
│ └── manage.py
└── db
<span >#<span >Subpackage for db<span >
├── <span >init<span >.py
└── models.py
目录结构
5,import
我们在与包glance同级别的文件中测试
1 2 glance.db.models.register_models()6,from ... import ...
需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法
我们在与包glance同级别的文件中测试 :
glance.db glance.db.models )7,__init__.py文件
不管是哪种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包下的__init__.py文件(我们可以在每个包的文件内都打印一行内容来验证一下),这个文件可以为空,但是也可以存放一些初始化包的代码。
8,绝对导入和相对导入
最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:
绝对导入:以glance作为起始
相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)
例如:我们在glance/API/version.py中想要导入glance/cmd/manage.py
在glance/API/<span >#<span >绝对导入<span >from glance.cmd <span >import<span > manage
manage.main()<span >#<span >相对导入
<span >from ..cmd <span >import<span > manage
manage.main()
特别需要注意的是:可以用import导入内置或者第三方模块(已经在sys.path中),但是要绝对避免使用import来导入自定义包的子模块(没有在sys.path中),应该使用from... import ...的绝对或者相对导入,且包的相对导入只能用from的形式。
glance.API <span >'''<span >执行结果:
importError: No module named 'policy'
<span >'''
<span >'''
<span >分析:
此时我们导入versions在versions.py中执行
import policy需要找从sys.path也就是从当前目录找policy.py,这必然是找不到的
<span >'''glance/├── <span >init.py <span >from glance <span >import<span > API
<span >from glance <span >import<span > cmd
<span >from glance <span >import<span > db
├── API
│ ├── <span >init.py <span >from glance.API <span >import<span > policy
<span >from glance.API <span >import<span > versions
│ ├── policy.py
│ └── versions.py
├── cmd <span >from glance.cmd <span >import<span > manage
│ ├── <span >init<span >.py
│ └── manage.py
└── db <span >from glance.db <span >import<span > models
├── </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080"><a href="https://www.jb51.cc/tag/init/" target="_blank" >__init__</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">.py└── models.py
绝对导入
glance/├── <span >init.py <span >from . <span >import API <span >#<span >.表示当前目录<span >from . <span >import<span > cmd
<span >from . <span >import<span > db
├── API
│ ├── <span >init.py <span >from . <span >import<span > policy
<span >from . <span >import<span > versions
│ ├── policy.py
│ └── versions.py
├── cmd <span >from . <span >import<span > manage
│ ├── <span >init<span >.py
│ └── manage.py <span >from ..API <span >import<span > policy
<span >#<span >..表示上一级目录,想再manage中使用policy中的方法就需要回到上一级glance目录往下找API包,从API导入policy
<span >
└── db <span >from . <span >import<span > models
├── </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080"><a href="https://www.jb51.cc/tag/init/" target="_blank" >__init__</a></span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000">.py└── models.py
相对导入
9,单独导入包
1 2 . 3 4 5 . manage10,软件开发规范
bin目录:存放执行脚本BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(<span >__file__<span >)))sys.path.append(BASE_DIR)<span >from core <span >import<span > core
<span >from conf <span >import<span > my_log_settings<span >if <span >name == <span >'<span >main<span >'<span >:
my_log_settings.load_my_logging_cfg()
core.run()<span >#<span >=============>conf目录:存放配置文件<span ><span >config.ini
<span >[DEFAulT]
user_timeout = 1000<span >
[egon]
password = 123<span >
money = 10000000<span >
[alex]
password =<span > alex3714
money=10000000000<span >
[yuanhao]
password =<span > ysb123
money=10
<span >#<span >settings.py
<span >import<span > os
config_path=r<span >'<span >%s\%s<span >' %(os.path.dirname(os.path.abspath(<span >file)),<span >'<span >config.ini<span >'<span >)
user_timeout=10<span >
user_db_path=r<span >'<span >%s\%s<span >' %(os.path.dirname(os.path.dirname(os.path.abspath(<span >file<span >))),\
<span >'<span >db<span >'<span >)
<span >#<span >my_log_settings.py
<span >"""<span >
logging配置
<span >"""
<span >import<span > os
<span >import<span > logging.config
<span >#<span > 定义三种日志输出格式 开始
<span >
standard_format = <span >'<span >[%(asctime)s][%(threadname)s:%(thread)d][task_ID:%(name)s][%(filename)s:%(lineno)d]<span >'<span > \
<span >'<span >[%(levelname)s][%(message)s]<span >' <span >#<span >其中name为getlogger指定的名字
<span >
simple_format = <span >'<span >[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s<span >'<span >
ID_simple_format = <span >'<span >[%(levelname)s][%(asctime)s] %(message)s<span >'
<span >#<span > 定义日志输出格式 结束
<span >
logfile_dir = r<span >'<span >%s\log<span >' %os.path.dirname(os.path.dirname(os.path.abspath(<span >__file__))) <span >#<span > log文件的目录
<span >
logfile_name = <span >'<span >all2.log<span >' <span >#<span > log文件名
<span >#<span > 如果不存在定义的日志目录就创建一个
<span >if <span >not<span > os.path.isdir(logfile_dir):
os.mkdir(logfile_dir)
<span >#<span > log文件的全路径
logfile_path =<span > os.path.join(logfile_dir,logfile_name)
<span >#<span > log配置字典
LOGGING_DIC =<span > {
<span >'<span >version<span >': 1<span >,<span >'<span >disable_existing_loggers<span >'<span >: False,<span >'<span >formatters<span >'<span >: {
<span >'<span >standard<span >'<span >: {
<span >'<span >format<span >'<span >: standard_format
},<span >'<span >simple<span >'<span >: {
<span >'<span >format<span >'<span >: simple_format
},},<span >'<span >filters<span >'<span >: {},<span >'<span >handlers<span >'<span >: {
<span >#<span >打印到终端的日志
<span >'<span >console<span >'<span >: {
<span >'<span >level<span >': <span >'<span >DEBUG<span >'<span >,<span >'<span >class<span >': <span >'<span >logging.StreamHandler<span >',<span >#<span > 打印到屏幕
<span >'<span >formatter<span >': <span >'<span >simple<span >'<span >
},<span >#<span >打印到文件的日志,收集info及以上的日志
<span >'<span >default<span >'<span >: {
<span >'<span >level<span >': <span >'<span >DEBUG<span >'<span >,<span >'<span >class<span >': <span >'<span >logging.handlers.RotatingfileHandler<span >',<span >#<span > 保存到文件
<span >'<span >formatter<span >': <span >'<span >standard<span >'<span >,<span >'<span >filename<span >': logfile_path,<span >#<span > 日志文件
<span >'<span >maxBytes<span >': 102410245,<span >#<span > 日志大小 5M
<span >'<span >backupCount<span >': 5<span >,<span >'<span >enCoding<span >': <span >'<span >utf-8<span >',<span >#<span > 日志文件的编码,再也不用担心中文log乱码了
<span > },<span >'<span >loggers<span >'<span >: {
<span >#<span >logging.getLogger(name)拿到的logger配置
<span >''<span >: {
<span >'<span >handlers<span >': [<span >'<span >default<span >',<span >'<span >console<span >'],<span >#<span > 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
<span >'<span >level<span >': <span >'<span >DEBUG<span >'<span >,<span >'<span >propagate<span >': True,<span >#<span > 向上(更高level的logger)传递
<span > },}
<span >def<span > load_my_logging_cfg():
logging.config.dictConfig(LOGGING_DIC) <span >#<span > 导入上面定义的logging配置
logger = logging.getLogger(<span >name) <span >#<span > 生成一个log实例
logger.info(<span >'<span >It works!<span >') <span >#<span > 记录该文件的运行状态
<span >if <span >name == <span >'<span >main<span >'<span >:
load_my_logging_cfg()
<span >#<span >=============>core目录:存放核心逻辑<span >
<span >core.py<span >import<span > logging
<span >import<span > time
<span >from conf <span >import<span > settings
<span >from lib <span >import<span > read_ini
config=<span >read_ini.read(settings.config_path)
logger=logging.getLogger(<span >name<span >)
current_user={<span >'<span >user<span >':None,<span >'<span >login_time<span >':None,<span >'<span >timeout<span >'<span >:int(settings.user_timeout)}
<span >def<span > auth(func):
<span >def wrapper(*args,<span >kwargs):
<span >if current_user[<span >'<span >user<span >'<span >]:
interval=time.time()-current_user[<span >'<span >login_time<span >'<span >]
<span >if interval < current_user[<span >'<span >timeout<span >'<span >]:
<span >return func(*args,*<span >kwargs)
name = input(<span >'<span >name>>: <span >'<span >)
password = input(<span >'<span >password>>: <span >'<span >)
<span >if<span > config.has_section(name):
<span >if password == config.get(name,<span >'<span >password<span >'<span >):
logger.info(<span >'<span >登录成功<span >'<span >)
current_user[<span >'<span >user<span >']=<span >name
current_user[<span >'<span >login_time<span >']=<span >time.time()
<span >return func(args,<span >kwargs)
<span >else<span >:
logger.error(<span >'<span >用户名不存在<span >'<span >)
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">return</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000"> wrapper
@auth
<span >def<span > buy():
<span >print(<span >'<span >buy...<span >'<span >)
@auth
<span >def<span > run():
</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff">print</span>(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">'''</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800000">
购物
查看余额
转账
<span >'''<span >)
<span >while<span > True:
choice = input(<span >'<span >>>: <span >'<span >).strip()
<span >if <span >not choice:<span >continue
<span >if choice == <span >'<span >1<span >'<span >:
buy()
<span >if <span >name == <span >'<span >main<span >'<span >:
run()
<span >#<span >=============>db目录:存放数据库文件<span >
<span >alex_Json<span ><span >egon_Json<span >#<span >=============>lib目录:存放自定义的模块与包<span >
<span >read_ini.py<span >import<span > configparser
<span >def<span > read(config_file):
config=<span >configparser.ConfigParser()
config.read(config_file)
<span >return<span > config
<span >#<span >=============>log目录:存放日志<span >
<span >all2.log[2017-07-29 00:31:40,272][MainThread:11692][task_ID:conf.my_log_settings][my_log_settings.py:75<span >][INFO][It works!]
[2017-07-29 00:31:41,789][MainThread:11692][task_ID:core.core][core.py:25<span >][ERROR][用户名不存在]
[2017-07-29 00:31:46,394][MainThread:12348][task_ID:conf.my_log_settings][my_log_settings.py:75<span >][INFO][It works!]
[2017-07-29 00:31:47,629][MainThread:12348][task_ID:core.core][core.py:25<span >][ERROR][用户名不存在]
[2017-07-29 00:31:57,912][MainThread:10528][task_ID:conf.my_log_settings][my_log_settings.py:75<span >][INFO][It works!]
[2017-07-29 00:32:03,340][MainThread:12744][task_ID:conf.my_log_settings][my_log_settings.py:75<span >][INFO][It works!]
[2017-07-29 00:32:05,065][MainThread:12916][task_ID:conf.my_log_settings][my_log_settings.py:75<span >][INFO][It works!]
[2017-07-29 00:32:08,181][MainThread:12916][task_ID:core.core][core.py:25<span >][ERROR][用户名不存在]
[2017-07-29 00:32:13,638][MainThread:7220][task_ID:conf.my_log_settings][my_log_settings.py:75<span >][INFO][It works!]
[2017-07-29 00:32:23,005][MainThread:7220][task_ID:core.core][core.py:20<span >][INFO][登录成功]
[2017-07-29 00:32:40,941][MainThread:7220][task_ID:core.core][core.py:20<span >][INFO][登录成功]
[2017-07-29 00:32:47,222][MainThread:7220][task_ID:core.core][core.py:20<span >][INFO][登录成功]
[2017-07-29 00:32:51,949][MainThread:7220][task_ID:core.core][core.py:25<span >][ERROR][用户名不存在]
[2017-07-29 00:33:00,213][MainThread:7220][task_ID:core.core][core.py:20<span >][INFO][登录成功]
[2017-07-29 00:33:50,118][MainThread:8500][task_ID:conf.my_log_settings][my_log_settings.py:75<span >][INFO][It works!]
[2017-07-29 00:33:55,845][MainThread:8500][task_ID:core.core][core.py:20<span >][INFO][登录成功]
[2017-07-29 00:34:06,837][MainThread:8500][task_ID:core.core][core.py:25<span >][ERROR][用户名不存在]
[2017-07-29 00:34:09,405][MainThread:8500][task_ID:core.core][core.py:25<span >][ERROR][用户名不存在]
[2017-07-29 00:34:10,645][MainThread:8500][task_ID:core.core][core.py:25][ERROR][用户名不存在]
二、异常处理
1,程序中难免出现错误,而错误分成两种:
1.语法错误(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正)
<span >#
<span >语法错误示范二<span >def<span > test:
<span >pass
<span >#<span >语法错误示范三
<span >print<span >(haha
语法错误
2.逻辑错误(逻辑错误)
num=input(>: <span >#<span >无法完成计算res1=1/<span >0
res2=1+<span >'<span >str<span >'
2,什么是异常
异常就是程序运行时发生错误的信号
3,python中的异常种类
在python中不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,不同的类对象标识不同的异常,一个异常标识一种错误
l=[,3]dic={:]s=
4,常用异常
/5+常用异常5,更多异常
更多异常三、异常处理1,什么是异常?
异常发生之后
异常之后的代码就不执行了
2,什么是异常处理
python解释器检测到错误,触发异常(也允许程序员自己触发异常)
程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关)
如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃,这就是异常处理
3,如何进行异常处理?
首先须知,异常是由程序的错误引起的,语法上的错误跟异常处理无关,必须在程序运行前就修正
一: 使用if判断式正常的计划:
num1=input(>: ) int(num1) = num1=input(<span >'<span >>>: <span >') <span >#<span >输入一个字符串试试<span >if<span > num1.isdigit():
int(num1) <span >#<span >我们的正统程序放到了这里,其余的都属于异常处理范畴
<span >elif<span > num1.isspace():
<span >print(<span >'<span >输入的是空格,就执行我这里的逻辑<span >'<span >)
<span >elif len(num1) ==<span > 0:
<span >print(<span >'<span >输入的是空,就执行我这里的逻辑<span >'<span >)
<span >else<span >:
<span >print(<span >'<span >其他情情况,执行我这里的逻辑<span >'<span >)<span >'''<span >
问题一:
使用if的方式我们只为第一段代码加上了异常处理,但这些if,跟你的代码逻辑并无关系,这样你的代码会因为可读性差而不容易被看懂
问题二:
这只是我们代码中的一个小逻辑,如果类似的逻辑多,那么每一次都需要判断这些内容,就会倒置我们的代码特别冗长。
使用if判断进行异常处理
总结:
1.if判断式的异常处理只能针对某一段代码,对于不同的代码段的相同类型的错误你需要写重复的if来进行处理。
2.在你的程序中频繁的写与程序本身无关,与异常处理有关的if,会使得你的代码可读性极其的差
3.if是可以解决异常的,只是存在1,2的问题,所以,千万不要妄下定论if不能用来异常处理。
二:python为每一种异常定制了一个类型,然后提供了一种特定的语法结构用来进行异常处理part1:基本语法try: 被检测的代码块except 异常类型: try中一旦检测到异常,就执行这个位置的逻辑f = open(g = (line.strip() <span >for line <span >in<span > f)<span >for line <span >in<span > g:
<span >print<span >(line)
<span >else<span >:
f.close()= open(= (line.strip() line <span >'''<span >
next(g)会触发迭代f,依次next(g)就可以读取文件的一行行内容,无论文件a.txt有多大,同一时刻内存中只有一行内容。
提示:g是基于文件句柄f而存在的,因而只能在next(g)抛出异常stopiteration后才可以执行f.close()
<span >'''<span >part2:异常类只能用来处理指定的异常情况,如果非指定异常则无法处理。= epart3:多分支s1 = (e)part4:万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,即:s1 = 'hello'try: int(s1)except Exception as e: print(e)
为什么不直接用万能异常?分两种情况去看:
1.如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么骚年,大胆的去做吧,只有一个Exception就足够了。
s1 = <span >#<span >如果你统一用Exception,没错,是可以捕捉所有异常,但意味着你在处理所有异常时都使用同一个逻辑去处理(这里说的逻辑即当前expect下面跟的代码块)<span >
Exception
2.如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。
s1 = (e)s1 = (e)part5:异常的其他机构s1 = (()part6:主动触发异常try: raise TypeError('类型错误')except Exception as e: print(e)part7:自定义异常class EvaException(BaseException): def __init__(self,msg): self.msg=msg def __str__(self): return self.msgpart8:try..except的方式比较if的方式的好处try:
raise EvaException('类型错误')
except EvaException as e:
print(e)
try..except这种异常处理机制就是取代if那种方式,让你的程序在不牺牲可读性的前提下增强健壮性和容错性
异常处理中为每一个异常定制了异常类型(python中统一了类与类型,类型即类),对于同一种异常,一个except就可以捕捉到,可以同时处理多段代码的异常(无需‘写多个if判断式’)减少了代码,增强了可读性
使用try..except的方式
1:把错误处理和真正的工作分开来2:代码更易组织,更清晰,复杂的工作任务更容易实现;3:毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了;
总结以上是内存溢出为你收集整理的python:包与异常处理全部内容,希望文章能够帮你解决python:包与异常处理所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)