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(包)

11466123-ae3c9250876417f2.png
Package

目录只有包含一个叫做 __init__.py的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块。
最简单的情况,放一个空的 :file: __init__.py就可以了,如果你用IDE的话,新建一个包就已经自建了一个 __init__.py了,当然、是个空文件。
我们这里新建一个名为 bao的包,使用如下形式引入:
11466123-1bc1c61a27350a24.png
新建包

#demo
import bao.hello
import bao.error

你可能会决定这有点多此一举,emmmmm,如果从事专业开发的话,项目一般会比较大,你不可能将全文件放到一块,甚至你会因为出现同名文件的问题十分烦恼,但有了包的存在这些问题就都解决了,不同包允许相同文件名的存在,在引入是也会区分,这些细节的把握,会让你的python学习之旅变得逼格满满。

学到这里,会不会觉得自己是真正意义上的在做一个项目了?

那接下来,要开始玩真的啦!

猜你喜欢

转载自blog.csdn.net/weixin_34150830/article/details/86928310