Python入门系列(六)——杂项
学习完前面的基础章节,正式准备进入I/O、OS、数据库、web之前。特地安排了这一章节《杂项》,来讨论下那些零零碎碎的小知识点,防止翻车。
目录:
一、切片
二、异常处理
三、模块
四、模块习惯
一、切片
序列类型允许通过下标的方式来获得某一个数据元素,或者通过指定下标范围来获得一组序列的元素,这种访问序列的方式叫做切片。其原理是调用内置函数slice()函数。
常见的序列类型就是list和tuple,当然,在这里字符串也可以看作一种list。
listdemo=[1,2,3,4]
tupledemo=1,2,3,4
strdemo='rabbit'
print(listdemo[0:2])
print(tupledemo[2:4])
print(strdemo[0:3])
#输出
[1, 2]
(3, 4)
rab
其实我们一直都在使用了,现在只是重申下概念和原理。
二、异常处理
1、try...except语句
第一次在python接触这个语句,是在上一章节。
我们来个0做分母的错误案例:
def error():
a=1/0
print(a)
error()
#输出:
a=1/0
ZeroDivisionError: division by zero
但是,我们不想看到这个错误!
def error():
try:
a=1/0
print(a)
except ZeroDivisionError:
print('你没错,老板说的都对')
error()
#输出:
你没错,老板说的都对
如果except 后不跟任何异常标识的话,任何报错你都看不到,讲真,这样做并不合适,完全不知道错在哪,就跟你为什么不知道你女盆友为什么哭一个道理。
在程序无异常时,执行完try的内容程序结束,但如果出现异常、就会比对except的内容,也就是说except后可跟多个异常标识,以元组格式书写。
2、try...except...else语句
你也可以看作是上一个语句的可选子句。如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。
def error():
try:
a=1/1 #这里临时修改成正常的
print(a)
except ZeroDivisionError:
print('你没错,老板说的都对')
else:
print('本次调试未翻车')
error()
#输出
1.0
本次调试未翻车
3、try ...finally语句
无论异常是否发生,在程序结束前,finally中的语句都会被执行。
def error():
try:
a=1/0
print(a)
except ZeroDivisionError:
print('你没错,老板说的都对')
finally:
print('我不管,反正程序运行完了')
error()
#输出
你没错,老板说的都对
我不管,反正程序运行完了
4、raise主动引发异常
def error():
a=1/1 #这里其实是对的哦!
raise ZeroDivisionError
error()
#输出:
raise ZeroDivisionError
ZeroDivisionError
5、自定义异常
你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。
class sorry(Exception):
pass
def error():
a=1/1
raise sorry
error()
#输出
raise sorry
__main__.sorry
6、assert 断言
格式:assert 条件 , 条件为false时的错误信息
assert 1+1>2,'小学就没学好'
#输出
assert 1+1>2,'小学就没学好'
AssertionError: 小学就没学好
三、模块
1、import 语句
我们知道,可以将系统内置模块或自定义模块,直接通过import的方式导入到当前项目中,然后可以直接使用。
习惯上我们知道自定义的模块(也就是一个py文件),放在python目录下或者当前项目目录下,当前项目就可以读到,但强迫症不禁要问一句,究竟是那些目录呢?
import sys
print('命令行参数如下:')
for i in sys.argv:
print(i)
print('\nPython 路径为:\n', sys.path, '\n')
#输出:
命令行参数如下:
C:/Users/rabbitmask/Desktop/Source code/Python/AuotScan/mok.py
Python 路径为:
['C:\\Users\\rabbitmask\\Desktop\\Source code\\Python\\AuotScan', 'C:\\Users\\rabbitmask\\Desktop\\Source code\\Python\\AuotScan', 'C:\\Users\\rabbitmask\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip', 'C:\\Users\\rabbitmask\\AppData\\Local\\Programs\\Python\\Python37\\DLLs', 'C:\\Users\\rabbitmask\\AppData\\Local\\Programs\\Python\\Python37\\lib', 'C:\\Users\\rabbitmask\\AppData\\Local\\Programs\\Python\\Python37', 'C:\\Users\\rabbitmask\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages', 'C:\\software\\PyCharm 2018.3.1\\helpers\\pycharm_matplotlib_backend']
sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。输出的目录即为我们可放置模块的目录,当然,习惯上还是当前项目位置。没有必要非得一级目录,毕竟python会自动检索当前目录以及子目录。
2、from … import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,白话就是只从指定py文件中拿取指定的函数等。
3、from … import * 语句用以
把一个模块的所有内容全都导入到当前的命名空间。
这里不要跟前两种混淆,前两个模块名跟在import后,这一招模块名跟在from后面,为什么要这么设置呢?
我们来做下对比:
1. 调用模块属性的区别
import 模块名
模块名.xxx = 引用
from 模块名 import *
xxx = 拷贝 # 能修改属性值
2. 私有属性两种导入的区别
#类中的私有属性会做一个名字重整
如:
class test()
self.__name
#__name 名字重整成 _test__name。
from 模块 import * : 导入模块时,会跳过私有属性;
import 模块 : 通过引用可以访问私有属性
如无必要,尽量避免使用第三种方法引入模块。
四、模块习惯
1、设置习惯
分享下我的模块头,除了前两行的标准注释,接着了逼格慢慢的banner,然后是个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释,方便后边回过头来看。最后是__author__
属性,用来记录作者名称。
#!/usr/bin/env python3
#_*_ coding:utf-8 _*_
'''
____ _ _ _ _ __ __ _
| _ \ __ _| |__ | |__ (_) |_| \/ | __ _ ___| | __
| |_) / _` | '_ \| '_ \| | __| |\/| |/ _` / __| |/ /
| _ < (_| | |_) | |_) | | |_| | | | (_| \__ \ <
|_| \_\__,_|_.__/|_.__/|_|\__|_| |_|\__,_|___/_|\_\
'''
'A test for demo in error '
__author__ = 'RabbitMask'
2、__name__
属性
一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__
属性来使该程序块仅在该模块自身运行时执行。
每个模块都有一个name属性,当其值是'main'时,表明该模块自身在运行,否则是被引入。
举个例子吧,我们建一个hello.py
:
#hello.py
def hello():
print('hello ,demo')
if __name__=='__main__':
hello()
else:
print("我只是被引入,我不想执行我的hello()函数")
#输出
hello ,demo
然后我们随便建一个py文件,名字无所谓,试图引入下该模块:
import hello
#输出
我只是被引入,我不想执行我的hello()函数
如果我们在这里强行使用hello()函数,会收到如下报错TypeError: 'module' object is not callable
,显然,是不被允许的。
话又说回来,我们一个项目引用了大量的包,看上的不过是其中的一些写好的方法,你希望自己在一个项目引入时,执行了各种脚本么?显然,请尽可能多的使用该属性。
3、Package(包)
Package目录只有包含一个叫做
__init__.py
的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。最简单的情况,放一个空的 :file:
__init__.py
就可以了,如果你用IDE的话,新建一个包就已经自建了一个__init__.py
了,当然、是个空文件。我们这里新建一个名为
bao
的包,使用如下形式引入:新建包
#demo
import bao.hello
import bao.error
你可能会决定这有点多此一举,emmmmm,如果从事专业开发的话,项目一般会比较大,你不可能将全文件放到一块,甚至你会因为出现同名文件的问题十分烦恼,但有了包的存在这些问题就都解决了,不同包允许相同文件名的存在,在引入是也会区分,这些细节的把握,会让你的python学习之旅变得逼格满满。
学到这里,会不会觉得自己是真正意义上的在做一个项目了?
那接下来,要开始玩真的啦!