Day10-包模块异常

0-1 变量和多态

'''
变量多态

python 中的变量(标识符),的类型是根据所代表的对象,进行自动推导得到的

'''

n = 1
print(type(n))

n = 3.14
print(type(n))

n = True
print(type(n))


def show():
    print('show')


n = show
n()
print(type(n))

0-2 类方法

定义格式:
@classmethod
def 方法名(cls,...):
	pass
	
调用格式:
类对象.类方法名

注意:
	在类方法中,不能使用self
	但是可以使用 cls,该参数用来表示 当前类对象,这个参数也是自动传递的\
	
应用场景:
一般在设计类时,如果有类方法,该类一般不会去实例对象,直接使用类对象来操作(比如:数学函数类)
一役用来定义工具类使用

Math.max(1,2)
'''类方法'''


class MyMath(object):
    # 定义一个类属性
    n = 999

    # 标准格式
    @classmethod  # 这是一个装饰 器,用来表示下面的方法是一个类方法
    def sum(cls, *args):
        print(cls.n)
        m = 0
        for i in args:
            m += i
        return m

    # @classmethod 是一个装饰 器,用来修饰一个方法成为类方法,当在执行该 类方法时,解释 会自动 将类对象传递到参数 cls中
    @classmethod
    def show(cls):
        print('show class method')


# 执行类方法
print(MyMath.sum(1, 2, 3, 4, 5))

mm = MyMath()
print(mm.sum(1, 2, 3, 4, 5))

MyMath.show()

0-3 静态方法

格式:
@staticmethod
def 方法名(参数列表....):
	pass
'''
静态方法
'''


# 设计 一个编码工具类
class EncodeUtil(object):
    n = 1

    # 编码方法
    @staticmethod
    def encode_data(data, format):
        print(f'对数据 {data} 使用 {format} 格式 进行了编码')

    # 解码方法
    @staticmethod
    def decode_data(data, format):
        print(EncodeUtil.n)
        print(f'对数据 {data} 使用 {format} 格式 进行了解编码')


# 测试
# eu = EncodeUtil()
# eu.encode_data('hello','utf-8')


EncodeUtil.encode_data('Hello', 'utf-8')
EncodeUtil.decode_data("hello", 'GBK')

​ 调用方式:
​ 同类方法
​ 类对象.静态方法名()


​ 设计目的:
​ 静态方法实际上就是放到类当中的一堆普通函数

​ 作用:
​ 静态方法同类方法相似,也是在不需要实例对象产生的条件下,可以使用静态方法来实现
​ 一般这两种方法,都是用在工具类的实现上.
​ 通过类,将一系列的功能方法进行整合到一起.



​ # 实例方法,必须通过实例对象调用执行,(第一个参数是当前调用该方法的实例)

​ # 类方法, 当不需要产生实例对象时,可以使用类方法来实现相应的代码功能,类方法可以直接
​ 使用类对象来调用,类方法的第一个参数是 cls,用来接收当前类对象,通过个参数,
​ 可以各个类方法中进行共享数据

# 静态方法, 作用同类方法相似,但是静态方法不接收任何默认参数(实例对象或类对象),静态方法
其实就是将一些相关联的普通方法使用类进行整合.

​ 类方法和静态方法,一般在使用时,大多数用来实现工具类.

1. 模块介绍

在Python中,一个.py文件就是一个模块

在Python,万物皆对象,模块也不例外

通过模块,可以有效的组织代码结构,让代码结构更加清晰

但是,初期可能让大家逻辑上更加混乱

2. 导入模块

导入模块是指:
在一个.py文件中,使用另外一个.py文件时,需要将这个文件导入
在一个模块中,使用另外一个模块时,需要将这个模块导入

import os
import time
import random
import sys 
import functools
'''自定义模块'''

n = 1


def show():
    print('show')


class Cat(object):
    def show(self):
        print('Cat_show')


print(n)
show()
tom = Cat()
tom.show()
'''
系统模块的使用
'''

import os
import time
import sys

print(os.getcwd())

# sleep 函数是一个time模块中定义的函数,用来让程序休眠,这是一个阻塞函数
time.sleep(3)
print('over')

# sys.argv 变量用来接收命令行参数
print(sys.argv)
方式一:
	import 模块名  (掌握)

方式二:
  	from 模块名 import 成员名 (掌握)

	特例:
	from 模块名 import * (掌握)

别名:
	import 模块名 as 别名
	from 模块名 import 成员名 as 成员别名
''''自定义模块'''

n = 1

def show():
    print('show')


class Cat(object):
    def show(self):
        print('Cat_show')
# 方式一
# import p_05模块
#
# # 使用时,需要使用模块对象.成员
# print(p_05模块.n)
#
# p_05模块.show()
#
# tom = p_05模块.Cat()
# tom.show()

# 方式一的别名形式
# 别名就是为复杂的模块名起一个代号
# 可以通过这个代号 来调用 模块中的相应的成员

# import p_05模块 as p5m
# print(p5m.n)
# p5m.show()
# p5m.Cat().show()
# p5m.Cat().show()


# 方式 二
# 导入指定模块中的指定成员
# from p_05模块 import n
# from p_05模块 import show
# from p_05模块 import Cat as CatClass
#
# # 当使用from-import 方式 导入 时,不需要再使用 模块名.成员 形式
# # 可以在当前文件中,直接 使用成员名,相当于将导入的成功复制到了本地一份
# print(n)
# show()
# CatClass().show()


# 这两种 方式 的区别
# 使用import时,可以将整个模块中的成员 都 导入 进来
# 使用 from-import 时,可以使用谁导入谁,更加节省资源
# 如果想使用 From-import 方式 ,也可以导入所有的成员
# 如果使用通配符 * 的方式 导入所有的成员,那么就不能使用 as 为成员起别名了
from p_05模块 import *

print(n)
show()
Cat().show()
两种导入方式区别:
1.import方式,是拿到了模块对象的引用地址,通过这个地址来使用模块中的成员
2.from-import方式,相当于将被导入模块中的成员,复制了一份到本地模块中.
    所以可以直接使用成员来访问被导入的成员
3.对于 import 方式来说,没有任何限制
4.对于from-import方式来说,有些成员是不能被导入的(有权限限制)
'''
两种导入 模块方式的区别
'''


# import p_06模块 as p6m
#
# print(p6m.x)
# print(p6m._y)
# print(p6m.__z)


# from p_06模块 import *
# print(x)
# 在使用这种 方式 导入 时,不会将私有的属性导入
# print(_y)
# print(__z)


# from -import 方式 的命令冲突问题

def x():
    print('x Function')


from p_06模块 import *

# x = 1

print(x)
x()

3. all

__all__ 是一个魔法属性,类型是一个列表,元素是字符串类型
作用:
	可以改变在使用 from-import 方式导入模块时,成员的导入规则 

3.1 from-import

在导入时,会产生命名冲突问题
在程序中最后的定后会起作用

4. 模块导入的搜索顺序(了解)

模块的分类:
	1.自定义模块
	2.系统模块
	3.第三方模块
'''
模块查找顺序
'''

import sys
# print(sys.path)

import p_06模块

import os

import pymysql

sys.path.append('C:\\Users\\KG\\Desktop')

import AAAA

print(AAAA.n)
print(sys.path)
查找顺序:
	1. 当前程序所在目录
	2. 在当前程序所在工程的根目录
	3. PYTHONPATH
	4. 系统目录
	5. site_packages 第三方模块的安装目录

name (掌握)
作用:
​ 如果__name__ 出现在当前执行的模块中时,得到的值是 main 这个字符串,用来表示执行的是当前文件
​ 如果__name__ 出现在在了被导入模块中时,得到的值是被导入模块的模块名

n = 1

def show():
    print('show')


class Cat(object):
    def show(self):
        print('Cat_show')


# 在当前文件下测试成员的使用

# 当使用 __name__ 属性在获取当前模块名时,会有两种 效果
# 如果当前模块文件是  主动执行 时,__name__ 得到的结果是字符串 __main__ 表示这是程序的入口
# 如果当前模块文件是  被动执行 时(被别人导入时),__name__ 得到的结果就是当前模块文件的文件名
print('name:', __name__)

if __name__ == '__main__':
    print(n)
    show()
    Cat().show()
'''
使用模块
'''
import p_08模块

print(__name__)

# 通过这个判断 来做为程序的程序 入口
if __name__ == '__main__':
    print('程序 的入口')

    print(p_08模块.n)

5. 包

包:就是一个文件夹

区别:
	在python3以前,包中是有一个文件 __init__.py ,没有该文件的就是一个普通 的文件夹,有该文件才是包
	在python3以后,不管有没有,都认为是一个包

6. 导入包中的模块

方式一:
	通过包和模块的路径,明确的告诉解释器,要导入哪个包里的哪个模块
	import 包名.模块名
	from 包名 import 模块名
	from 包名.模块名 import 成员名


方式二:
	import 包名
	from 包名 import *

	在导入时,不会指定模块名,只指定包名
	这时,默认情况下(__init__.py 为空)哪个模块都不会导入

	为了能让模块正常导入,这里需要 __init__.py 文件中设置可以被导入的模块
	通过方式:
	from . import 模块名

	注意:
	__all__ 只对 from 包名 import * 方法生效,对 import 包名 方式无效
	__all__ 在 __init__.py 文件中的使用了解即可


​ 如果包有很多层级的情况:
​ www.ittest.cn
​ cn
​ ittest
​ python
​ java
​ c++

​ from cn.ittest.python import database

www.ittest.cn
cn
ittest
web
a.py
b.py
c.py
spider
a.py
b.py
c.py

'''
导入包中的模块
'''
# 导入 normal_dir 这个包中的 a 模块
import normal_dir.a

print(normal_dir.a.m)

import normal_dir.a as nda

print(nda.m)

# 使用from-import 方式导入
# 从  normal_pack 包中导入 b 模块
# 使用时,需要指定包名. 成员
from normal_pack import b

print(b.n)

# 从 normal_pack的 b 模块中,导入 b 模块中的所有成员
from normal_pack.b import *

print(n)

​ # 小结模块导入:
​ 1. 导入模块:
​ 两种方式
​ import 包名.模块名 -> 包名.模块名.成员
​ from 包名.模块名 import 成员名 -> 直接使用成员
​ from 包名 import 模块名 -> 模块名.成员
​ from 包名.模块名 import * -> 直接使用成员

2. all 这个魔法属性,会影响 from - import * 这种导入方式的模块
在all 中指定的模块或成员会被导入,没有指定的不会被导入

3. 了解模块导入时的搜索路径
	sys模块中的path变量中保存了搜索路径
	a. 当前程序所在同级目录
	b. 当前程序所在工程的根目录
	c. PYTHONPATH 环境变量中设置的目录
	d. 系统目录
	e. site-packages 这个第三方模块安装目录
	
4. 包
	包就是一个文件夹
	包和普通文件夹的功能在于 包中有一个 __init__.py 文件
	
	该文件的作用是在只导入包时,指定可以导入的模块有哪些
	如果这个文件是空的,那么在导入这个包时,不会导入任何模块
	
	在指定可以导入的模块时, 可以使用  from . import 可导入模块名

# import cn.itcast.web.a as weba1
# print(weba1.m)
#
# from cn.itcast.web import a as weba2
# print(weba2.m)
#
# from cn.itcast.web.a import *
# print(m)

# 想直接导入这个 web 包
# 在这里,如果只导到包的位置,那么通过 这个包去找模块时,会报错,因为不确定要导入哪个模块
# 需要在包中的 __init__.py 中,告诉解释器,当导入包时,应该导入哪些模块
# import cn.itcast.web as web
# print(web.a.m)
# print(web.b.n)


# from cn.itcast import web
# print(web.a.m)
# print(web.b.n)



# 小结:
'''
当在使用 import 方式 ,或from-import 方式 导入包时,
需要在 __init__.py 文件中,明确的指出可以被导入的模块有哪些
使用 from . import 模块名 形式指定 
如果在该 文件中没有指定 可以导入的模块时,默认不导入任何模块
'''

import cn.itcast.web as web
print(web.a.m)

from cn.itcast.web import *
print(a.m)
print(b.n)

7.异常概述

异常: 不正常
程序在执行过程中发生了不可预知的问题.
导致程序崩溃 

NameError
TypeError
ValueError
AttribitueError
SyntaxError
IndexError

改- index()
# class 语法错误 (Exception)
#
#    class 简单语法错误 (语法错误)
#         没有缩进
#         使用全角符号
#
#     高级语法错误
#         逻辑性错误

  1. try:
    可能会出现异常问题的代码
    except Exception as e:
    当出现异常时,解决异常的代码
    else:
    当没有出现异常时,正常执行的代码
    finally:
    无论是否出现异常,都会执行这里的代码

    语法糖

    with open('a.txt','r') as f:
    f.read()

    '''
    使用 try-except 进行基本的异常处理
    
    '''
    
    s = 'Hello'
    
    try:
        # 这句代码会发生异常
        print(s.index('O'))
    # except ValueError:
    except Exception:
        print('查找的子串不存在')
    
    # 使用Try 来尝试执行 后面语句 块中的代码 ,如果代码 发生异常问题
    # 那么异常信息就会被 except 捕捉到,可以在 except 后面进行异常处理
    # 如果代码 没有异常,那么程序就正常运行,不会执行except 后的代码
    
    
    print('over')
    
  2. 异常的传递

    当代码出现了很层级的调用时,在其中发生了异常,如果没有处理这个异常,这个异常会自动向上抛出
    如果上层也没有处理,那么再继续向上抛出,直到抛到解释器,解释器默认处理异常的方式就是中断程序,
    将异常信息显示控制台上

8. 异常处理

语法:
	try:
		可能出现异常的代码
	except Exception:
		当异常发生时,处理异常的代码

8. 多个异常的处理

将多个异常通过圆括号包裹成一个元组

语法:
	try:
		可能出现异常的代码
	except (异常1,异常2,...):
		当异常发生时,处理异常的代码

8-1: 异常别名-获取异常信息

语法:
	try:
		可能出现异常的代码
	except (Exception,... )as e:
		print(e)
		当异常发生时,处理异常的代码
'''
注意:同时捕捉多个异常,但是同一时刻只能有一个异常发生
'''

try:
    # n = 1
    n / 0
# except (ZeroDivisionError, NameError) as e:
# except Exception as e:
except:
    print('出现异常了')

9. else:(可选的,理解)

在异常处理时,当没有异常发生的情况后,需要执行的代码,放到 else 语句块
'''
异常处理子句,else 用来处理没有异常的的情况
'''

try:
    f = None
    f = open('b.txt', 'r')
except Exception as e:
    print('要打开的文件不存在')
    print(e)
else:
    # 对文件的读取操作
    print('else 是当没有出现异常时,执行的else语句 块')
    print(f.read())
finally:
    # 不管是否出现异常,都要执行这个语句块
    # 一般这个模块中,主要写的内容 是资料关闭或回收
    # 比如,文件的关闭,网络连接的关闭,数据库的关闭
    print('无论是否出现异常,都会执行finally语句 块')
    if f != None:
        f.close()

with open('a.txt', 'r') as f:
    print(f.read())

10. finally:(可选的,掌握)

无论异常是否发生,都会执行这个语句块里的内容

应用:
	一般应用在资源需要关闭资源的场景上
	比如:文件的关闭,网络连接的关闭,数据库的关闭

11. 异常的传递

在发生异常时,异常的发生点可能在很深的函数调用过程中,这时如果不处理异常的话,异常会被一层一层的抛出
如果谁都没有处理,最终抛给解释器,解释是没办法处理异常,解释会将异常信息显示到终端
'''
异常的传递
'''


def func_a():
    print('Func a run ...')
    func_b()


def func_b():
    print("Func b run ...")

    try:
        func_c()
    except Exception:
        print('你的除数为0了')


def func_c():
    print('Func c run ...')
    # try:
    #     print(1 / 0)
    # except Exception:
    #     print('你的除数为0了')

    print(1 / 0)


func_a()

12. 自定义异常

格式:
class 异常名Error(Exception):
	def __init__(self,msg=''):
		self.__msg = msg

	def __str__(self):
		return self.__msg



class CustomError(Exception):
	pass
'''自定义异常

格式 :
class 异常名Error(Exception):
    pass
'''


# 定义一个用来判断当前手机号是否有非法字符的异常
class PhoneNumberNotDigitError(Exception):
    pass


# 定义一个用来判断手机号位数是否合法的异常
class PhoneNumberLengthError(Exception):
    def __init__(self, msg):
        self.__msg = msg

    def __str__(self):
        return self.__msg


# 定义一个函数,用来获取一个电话号码
def get_phone_number():
    pn = input('请输入一个11位的手机号:')
    if pn.isdigit() == False:
        # 抛出自定义的异常
        raise PhoneNumberNotDigitError()
    elif len(pn) != 11:
        raise PhoneNumberLengthError('手机号位数不正确')

    return '输入的手机号是合法的:' + pn

# get_phone_number()

13. 自定义异常的抛出

raise 异常对象


​ raise 类名
​ raise 类名()

from p_16自定义异常 import *

try:
    num = get_phone_number()
except (PhoneNumberLengthError, PhoneNumberNotDigitError) as e:
    print(e)
else:
    print(num)



posted @ 2023-01-23 18:54  李好秀  阅读(18)  评论(0编辑  收藏  举报