IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python 基础入门笔记(四)———— 文件操作、面向对象、异常、模块包 -> 正文阅读

[Python知识库]Python 基础入门笔记(四)———— 文件操作、面向对象、异常、模块包


一、文件操作

1.1 文件的基本操作

1.1.1 打开

打开文件操作步骤:

  1. 打开文件
  2. 读写等操作
  3. 关闭文件

用 open 函数,打开已经存在的文件,或者创建一个新文件,语法: open(name, mode)

  • name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
  • mode:设置打开文件的模式(访问模式):只读、写入、追加等。

1.1.2 打开文件模式

模式描述
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+打开一个文件用于读写。文件指针将会放在文件的开头。
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
w+打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
a打开一个文件用于追加。如果该文件已存在、文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

注意:

  • 基本模式有:r w a,其他的模式是在其基础上泛生而来。
  • 模式中带有 b,代表二进制。模式中带有 +,代表可读可写。

示例1:

# r: 如果文件不存在,则报错:不支持写入操作,表示只读
f = open('test.txt', 'r')
# f = open('test1.txt', 'r')  # 文件不存在,报错
# f.write('aa')  # 报错
con = f.read()
print(con)
f.close()

# w:只写,如果文件不存在,新建文件:执行写入,会覆盖原有内容
f = open('text1.txt', 'w')
f.write('bbb')
f.close()

# a:追加,如果文件不存在,新建文件:在原有内容基础上,追加新内容
f = open('test.txt', 'a')
f.write('lalala')
f.close()

# 访问模式参数可以省略,如果省略表示访问模式为 r
f = open('text.txt')
f.close()

示例2:

# w+:没有该文件会新建;w 特点,文件指针在开头,用新内容覆盖原内容
# 如果只读不写,文件内容会空
f = open('test.txt', 'w+')
f.write("haha")  # 此时文件新内容覆盖原内容,文件指针在末尾
con = f.read()  # 因此接着读,将不会读出内容
print(con)
f.close()

1.1.3 文件对象方法

1.1.3.1 写

语法: 文件对象.write( '内容')

# 1. 打开文件
f = open('test.txt', 'w')
# 2.文件写入
f.write('hello world')
# 3. 关闭文件
f.close()

注意:

  1. w 和 a 模式:如果文件不存在则创建该文件如果文件存在,w 模式先清空再写入,a 模式直接末尾追加。
  2. r 模式:如果文件不存在则报错。

1.1.3.2 读

  • 设 test.txt 文件中内容如下:
    在这里插入图片描述

  • read()

    语法: 文件对象.read( num)
    num 表示要从文件中读取的数据的长度(单位是字节),如果没有传入 num,那么就表示读取文件中所有的数据。

    f = open('test.txt', 'r')
    # 换行符 \n 会有字节占位
    # read 不写参数表示读取所有
    print(f.read())
    print(f.read(4))  # 此时文件的指针在末尾, 所以不会读取任何数据
    f.close()
    

    结果如下:
    在这里插入图片描述

  • readlines()

    readlines 可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。

    f = open('test.txt', 'r')
    con = f.readlines()
    print(con)  # ['aaa\n', 'bbb\n', 'ccc']
    f.close()
    
  • readline()
    readline 每次打印一行数据,文件指针会后移。

    f = open('test.txt', 'r')
    con = f.readline()
    print(f'第??:{con}')
    con = f.readline()
    print(f'第二?:{con}')
    con = f.readline()
    print(f'第三?:{con}')
    f.close()
    

    结果如下:
    在这里插入图片描述


1.1.2.3 seek()

作用: 用来移动文件指针

语法: 文件对象.seek(偏移量,起始位置)

起始位置: 0:文件开头?1:当前位置 ?2:文件结尾

f = open('test.txt', 'r+')
f.seek(2, 0)  # 开头偏移两个字符
con = f.read()
print(con)
f.close()

结果如下:
在这里插入图片描述


1.1.4 关闭

文件对象.close()


1.2 文件备份

备份文件步骤:

  1. 接收用户输入的文件名
  2. 规划备份文件名
  3. 备份文件写入数据

代码如下:

# 1. 用户输入目标文件名字 
old_name = input('请输入要备份的文件名:')

# 2. 规划备份文件的名字
# 2.1 提取目标文件后缀
index = old_name.rfind('.')  # 从右侧找 '.',如:sound.txt.mp3  是 mp3 文件类型

if index > 0: # 限制文件格式为 “xxx.后缀” 才可备份 
    postfix = old_name[index:]

# 2.2 组织备份文件名, xx[备份]后缀
new_name = old_name[:index] + '[备份]' + postfix

# 3. 备份文件写入数据(数据和原文件一样)
# 3.1 打开 原文件 和 备份文件
old_f = open(old_name, 'rb')  # 以二进制打开
new_f = open(new_name, 'wb')

# 3.2 原文件读取,备份文件写入
# 如果不确定目标文件大小,循环读取写入,当读取出来的数据没有了则终止循环
while True:
    con = old_f.read(1024)
    if len(con) == 0:
        break
    new_f.write(con)

# 3.2 关闭文件
old_f.close()
new_f.close()

1.3 文件和文件夹操作

在 Python 中文件和文件夹的操作要借助 os 模块里面的相关功能。

导入 os 模块:import os

1.3.1 文件/文件夹重命名

os.rename(目标文件名,新文件名)

1.3.2 删除文件

os.remove(目标文件名)

1.3.3 创建文件夹

os.mkdir(文件夹名字)

1.3.4 删除文件夹

os.rmdir(文件夹名字)

1.3.5 获取当前目录

os.getcwd()

1.3.6 改变默认目录

os.chdir(目录)

1.3.7 获取目录列表

os.listdir(?目录)

应用:批量重命名

# flag = 1:把文件夹所有文件重命名 python-xxx
# flag = 2:删除python-重命名

import os

# 构造内置条件的数据
flag = 2

# 1. 找到所有文件:获取文件夹的目录列表
file_list = os.listdir()
print(file_list)

# 2. 重构名字
for i in file_list:
    if flag == 1:
        new_name = 'python-' + i
    elif flag == 2:
        num = len('python-')
        new_name = i[num:]

	# 3. 重命名
    os.rename(i, new_name)

二、面向对象基础

2.1 面向对象的实现方法

2.1.1 定义类

语法:

class 类名():
	代码
	......

注意: 类名遵循大驼峰命名习惯,即首字母大写

扩展

2.1.2 创建对象

语法: 对象名 = 类名()

注意: 创建对象的过程也叫实例化对象。

2.1.3 self

self 指的是调用该函数的对象。

示例:

# 定义洗衣机类
class Washer():
    def wash(self):
        print("洗衣服")
        print(self)

# 创建对象
haier1 = Washer()
print(haier1)  # <__main__.Washer object at 0x000001455A806D70>

# 使用实例方法
haier1.wash()  # 洗衣服
               # <__main__.Washer object at 0x000001455A806D70>
               # self 指的是调用该函数的对象
               # self 和 对象得到的结果是一致的,都是当前对象的内存中存储地址。

# 创建两个对象
haier2 = Washer()  # 不同对象存储地址不一样
print(haier2)

2.2 添加和获取对象属性

添加对象属性的方式有两种:类外面添加、类里面添加

  1. 类外面添加和获取对象属性

    语法:对象名.属性名

  2. 类里面添加获取对象属性

    语法:self.属性名

示例:

class Washer():
	def __init__(self):
        self.height = 300  # 类内 添加属性,一般在 __init()__ 方法中添加类内属性,即实例属性
        
    def print_info(self):
        print(f'洗衣机的宽度:{self.width}')  # 类内 获取属性

haier = Washer()
haier.width = 400  # 类外 添加属性
print(f'洗衣机的宽度:{haier.width}')  # # 类外 获取属性

haier.print_info()

2.3 魔法方法

__xx__() 的函数叫做魔法方法,指的是具有特殊功能的函数。

2.3.1 init()

__init__() 方法的作用:初始化对象,分为带参数和不带参数两种。

  1. 不带参数:

    class Washer():
        # __init__ 初始化
        def __init__(self):
            self.width = 400
            self.height = 400
    
        def print_info(self):
            print(f'洗衣机的宽度:{self.width}')  # 洗衣机的宽度:400
            print(f'洗衣机的宽度:{self.width}')  # 洗衣机的宽度:400
    
    haier = Washer()
    haier.print_info()
    
  2. 带参数:

    class Washer():
        # 带参数__init__ 初始化
        def __init__(self, width, height):
            self.width = width
            self.height = height
    
        def print_info(self):
            print(f'洗衣机的宽度:{self.width}')  # 洗衣机的宽度:100
            print(f'洗衣机的宽度:{self.width}')  # 洗衣机的宽度:200
    
    haier1 = Washer(100,200)
    haier1.print_info()
    
    # haier2 = Washer()  # 报错
    

注意︰

  1. __init__() 方法,在创建一个对象时默认被调用,不需要手动调用
  2. __init__(self) 中的 self 参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去。

2.3.2 str()

当使用 print 输出对象的时候,默认打印对象的内存地址。如果类定义了__str__方法,那么就会打印从在这个方法中 return 的数据。

示例:

class Washer():
    def __str__(self):
        return '洗衣机类的解释说明'

haier1 = Washer()
print(haier1)  # 洗衣机类的解释说明

2.3.3 del()

当删除对象时,解释器也会默认调用 __del__() 方法。

class Washer():
    def __del__(self):
       print('删除')

haier = Washer()
del haier  # 删除

三、面向对象继承

3.1 旧式类与新式类

  • 经典类或旧式类:

    不由任意内置类型派生出的类,称之为经典类。

    class类名:
    	代码
    	......
    
  • 新式类:
    Python中,所有类默认继承 object 类,object 类是顶级类或基类,其他子类叫做派生类。

    class类名(object):
    	代码
    	......
    

3.2 单继承

# 父类 A
class A(object):
    def __init__(self):
        self.num = 1

    def info_print(self):
        print(self.num)

# 子类 B
class B(A):
    pass  # 作用是省略

result = B()
result.info_print()  # 1
print(result.num)  # 1

3.3 多继承

多继承:一个类同时继承了多个父类。

# 父类A
class A(object):
    def __init__(self):
        self.num_a = 1

    def info_print(self):
        print(f'A类:{self.num_a}')

# 父类B
class B(object):
    def __init__(self):
        self.num_a = 2

    def info_print(self):
        print(f'B类:{self.num_a}')

# 子类
class C(A, B):
    pass

cc = C()
print(cc.num_a)  # 1
cc.info_print()  # A类:1

注意:

  1. 如果一个类继承多个父类,默认使用第一个父类的同名属性和方法
  2. 单继承中,子类默认继承父类的所有属性和方法
  3. 多继承中,子类继承第一个父类的所有属性和所有类的方法
  4. 两种继承方式子类都可以重写父类属性和方法

如:

# 父类A
class A(object):
    def __init__(self):
        self.num_a = 1
        self.num_aa = 2

    def info_print(self):
        print(f'A类:{self.num_a}')

# 父类B
class B(object):
    def __init__(self):
        self.num_a = 3
        self.num_b = 4

    def info_print(self):
        print(f'B类:{self.num_a}')

    def info_print2(self):
        print(f'B类:{self.num_a}')

# 子类
class C(A, B):
    pass

cc = C()
 # vars(object):返回对象的属性
print(vars(cc)) # {'num_a': 1, 'num_aa': 2}
print(cc.num_a)   # 1
print(cc.num_aa)  # 2  -- 第一个父类特有的属性
# print(cc.num_b)   # 报错  -- 第二个父类特有的属性
cc.info_print()   # A类:1  
cc.info_print2()   # B类:1  -- 第二个父类特有的方法

3.4 子类重写父类同名方法和属性

如果一个类继承多个父类,子类会调用子类同名属性和方法

# 父类A
class A(object):
    def __init__(self):
        self.num = 1

    def info_print(self):
        print(f'A父类:{self.num}')

# 父类B
class B(object):
    def __init__(self):
        self.num = 2

    def info_print(self):
        print(f'B父类:{self.num}')

# 子类
class C(A, B):
    def __init__(self):
        self.num = 33

    def info_print(self):
        print(f'子类:{self.num}')


cc = C()
print(cc.num)  # 33
cc.info_print()  # 子类:33

print(C.__mro__)  # 通过__mro__方法来获取这个类的调用顺序
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

3.5 子类调用父类同名方法和属性

# 父类 A
class A(object):
    def __init__(self):
        self.num = 11

    def info_print(self):
        print(f'A父类:{self.num}')

# 父类 B
class B(object):
    def __init__(self):
        self.num = 22

    def info_print(self):
        print(f'B父类:{self.num}')

# 子类 C
# 父类A
class A(object):
    def __init__(self):
        self.num = 11

    def info_print(self):
        print(f'A父类:{self.num}')

# 父类B
class B(object):
    def __init__(self):
        self.num = 22

    def info_print(self):
        print(f'B父类:{self.num}')

# 子类C
class C(A, B):
    def __init__(self):
        self.num = 33

    def info_print(self):
        # 加自己的初始化的原因:如果不加这个自己的初始化, num 属性值是上次调用的 init 内的 num 属性值
        self.__init__()
        print(f'子类:{self.num}')

    # 子类调用父类同名方法和属性
    def info_a_print(self):
        # 父类类名.函数()
        # 再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在 init 初始化位置,所以需要再次调用 init
        A.__init__(self)
        A.info_print(self)

    def info_b_print(self):
        B.__init__(self)
        B.info_print(self)

cc = C()
print(cc.num)  # 33

cc.info_a_print()  # A父类:11  --- 若没有 A.__init__(self),则同名属性为 子类C 属性值
cc.info_b_print()  # B父类:22  --- 若没有 A.__init__(self),则同名属性为上一个 A类 属性值
cc.info_print()  # 子类:33  --- 若没有 self.__init__(),则同名属性为上一个 B类 属性值

3.6 多层继承

# 父类 A
class A(object):
    def __init__(self):
        self.num = 11

    def info_print(self):
        print(f'A父类:{self.num}')

# 父类 B
class B(object):
    def __init__(self):
        self.num = 22

    def info_print(self):
        print(f'B父类:{self.num}')

# 子类C
class C(A, B):
    def __init__(self):
        self.num = 33

    def info_print(self):
        # 加自己的初始化的原因:如果不加这个自己的初始化, num 属性值是上次调用的 init 内的 num 属性值
        self.__init__()
        print(f'子类:{self.num}')

    # 子类调用父类同名方法和属性
    def info_a_print(self):
        # 父类类名.函数()
        # 再次调用初始化的原因:这里想要调用父类的同名方法和属性,属性在 int 初始化位置,所以需要再次调用 init
        A.__init__(self)
        A.info_print(self)

    def info_b_print(self):
        B.__init__(self)
        B.info_print(self)

class D(C):
    pass

dd = D()
dd.info_print()  # 子类:33
dd.info_a_print()  # A父类:11
dd.info_b_print()  # B父类:22

3.7 super()调用父类方法

使用super() 可以自动查找父类。调用顺序遵循 __mro__类属性的顺序。比较适合单继承使用。
super() 包括 有参数无参数 两种方式。

  • B类继承A类,C类继承B类,一次性调用父类的同名属性和方法,代码如下:

    # 父类A
    class A(object):
        def __init__(self):
            self.num = 11
    
        def info_print(self):
            print(f'A父类:{self.num}')
    
    # 父类B
    class B(A):
        def __init__(self):
            self.num = 22
    
        def info_print(self):
            print(f'B父类:{self.num}')
            # 有参数 super:super(当前类名, self).函数()
            # super(B, self).__init__()
            # super(B, self).info_print()
    
            # 无参数super
            super().__init__()
            super().info_print()
    
    # 子类C
    class C(B):
        def __init__(self):
            self.num = 33
    
        def info_print(self):
            # 加自己的初始化的原因:如果不加这个自己的初始化, num 属性值是上次调用的 init 内的 num 属性值
            self.__init__()
            print(f'子类:{self.num}')
    
        # 一次性调用父类的同名属性和方法
        def info_a_b_info(self):
            # 法一:
            # A.__init__(self)
            # A.info_print(self)
            # B.__init__(self)
            # B.info_print(self)
    
            # 法二:super()
            # 有参数 super:super(当前类名, self).函数()
            # super(C, self).__init__()
            # super(C, self).info_print()
    
            # 无参数super
            super().__init__()
            super().info_print()
    
    cc = C()
    cc.info_a_b_info()  # B父类:22  A父类:11
    
  • C 类同时继承 A 类与 B 类,代码如下:

# 父类A
class A(object):
    def __init__(self):
        self.num = 11

    def info_print(self):
        print(f'A父类:{self.num}')

# 父类B
class B(object):
    def __init__(self):
        self.num = 22

    def info_print(self):
        print(f'B父类:{self.num}')

# 子类C
class C(A, B):
    def __init__(self):
        self.num = 33

    def info_print(self):
        # 加自己的初始化的原因:如果不加这个自己的初始化, num 属性值是上次调用的 init 内的 num 属性值
        self.__init__()
        print(f'子类:{self.num}')

    # 一次性调用父类的同名属性和方法
    def info_a_b_info(self):

        # 无参数super
        super().__init__()
        super().info_print()

cc = C()
cc.info_a_b_info()  # A父类:11   ---默认调用第一个父类的方法

3.8 私有权限

??python中,实例属性和方法若设置为私有权限,则 该实例属性或实例方法不继承给子类,并且一般定义函数名 get_xx 用来获取私有属性,定义set_xx用来修改私有属性值。

设置私有权限的方法:在属性名和方法名前面加上两个下划线___

# 父类 A
class A(object):
    def __init__(self):
        self.num = 11
        # 定义私有属性  两道下划线
        self.__num = 22

    def info_print(self):
        print(f'A父类:{self.num}')
        self.__info_print()

    # 定义私有方法
    def __info_print(self):
        print(f'私有方法:{self.__num}')

    def get_num(self):
        return self.__num

    def set_num(self):
        self.__num = 500

# 子类 B
class B(A):
    pass

bb = B()
# print(bb.num)  # 11
# print(bb.__num)   # 报错
# bb.__info_print()  # 报错 私有方法报错,继承不了
bb.info_print()  # A父类:11 私有方法:22

print(bb.get_num())  # 22
bb.set_num()
print(bb.get_num())  # 500

三、面向对象其他

3.1 面向对象三大特征

  • 封装:将属性和方法书写到类的里面的操作即为封装,并且封装可以为属性和方法添加私有权限。
  • 继承
    • 单继承中,子类默认继承父类的所有属性和方法
    • 多继承中,子类继承第一个父类的所有属性和所有类的方法
    • 两种继承方式子类都可以重写父类属性和方法。
  • 多态:传入不同的对象,产生不同的结果。

3.2 多态

定义︰ 多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的结果。

class Dog(object):
    def work(self): # 父类提供统一的?方法,哪怕是空方法
        print('指哪打哪...')

class ArmyDog(Dog): # 继承Dog类
    def work(self):  # ?子类重写?父类同名?方法
        print('追击敌人...')

class DrugDog(Dog):
    def work(self):
        print('追查毒品...')

class Person(object):
    def work_with_dog(self, dog): # 传?入不不同的对象,执?行行不不同的代码,即不不同的work函数
        dog.work()


ad = ArmyDog()
dd = DrugDog()
person = Person()
person.work_with_dog(ad)  # 追击敌人...
person.work_with_dog(dd)  # 追查毒品...

3.3 类属性和实例属性

3.3.1 类属性

  • 设置和访问类属性
    类属性就是类对象所拥有的属性,它被该类的所有实例对象 所共有类属性可以使用类对象或实例对象访问。
  • 修改类属性
    类属性只能通过类对象修改,不能通过实例对象修改。 如果通过实例对象修改类属性,表示的是创建了一个实例属性

示例:

class Dog(object):
    tooth = 10  # 类属性

dog = Dog()

# 访问
print(Dog.tooth)  # 10
print(dog.tooth)  # 10

# 修改
# 1. 通过类来修改
Dog.tooth = 20
print(Dog.tooth)  # 20

# 2. 通过对象来修改
dog.tooth = 40  # 不是修改类属性值,而是为 dog 对象添加一个属性
print(Dog.tooth)  # 20  -- 修改失败
print(dog.tooth)  # 40

3.3.2 实例属性

示例属性,也叫对象属性。其可通过类内类外都可修改和获取。

示例:

class Washer():
	def __init__(self):
        self.height = 300  # 类内 添加属性,一般在 __init()__ 方法中添加类内属性,即实例属性
        
    def print_info(self):
        print(f'洗衣机的宽度:{self.width}')  # 类内 获取属性

haier = Washer()
haier.width = 400  # 类外 添加属性
print(f'洗衣机的宽度:{haier.width}')  # # 类外 获取属性

haier.print_info()

注意: 实例属性要求每个对象为其 单独开辟一份内存空间来记录数据,而类属性为全类所共有,仅占用一份内存,更加节省内存空间。


3.4 类方法和静态方法

3.4.1 类方法

类方法特点:

  • 第一个形参是类对象的方法

  • 需要用装饰器 @classmethod 来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数。

示例:

class Dog(object):
    __tooth = 10

    @classmethod  # 类方法:与类属性配合使用
    def get_tooth(cls):
        return cls.__tooth

dog = Dog()
result = dog.get_tooth()
print(result)  # 10

使用场景:

  • 类方法一般和类属性配合使用。
  • 当方法中需要使用 类对象(如:访问私有类属性等)时,定义类方法

3.4.2 静态方法

静态方法特点:

  • 需要通过装饰器 @staticmethod 来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)
  • 静态方法也能够通过 实例对象类对象 去访问。

示例:

class Dog(object):
    @staticmethod
    def info_print():
        print('这是静态方法')

dog = Dog()
# 静态方法既可以使用对象访问有可以使用类访问
dog.info_print()  # 这是静态方法
Dog.info_print()  # 这是静态方法

使用场景:

  • 当方法中 既不需要使用实例对象(如:实例对象,实例属性),也不需要使用类对象(如:类属性、类方法、创建实例等)时,定义静态方法。
  • 取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗

四、异常

4.1 异常语法

  • 一般写法

    try:
    	可能发生错误的代码
    except :
    	如果出现异常执行的代码
    
  • 捕获指定异常

    try:
    	可能发生错误的代码
    except 异常类型:
    	如果捕获到该异常类型执行的代码
    
  • 捕获多个指定异常

    try:
    	可能发生错误的代码
    except (异常类型1, 异常类型2, ...):
    	如果捕获到该异常类型执行的代码
    
  • 捕获异常描述信息

    try:
    	可能发生错误的代码
    except 异常类型 as result:
    	print(result)  # 打印描述信息
    	如果捕获到该异常类型执行的代码
    
  • 捕获所有异常

    try:
    	可能发生错误的代码
    except Exception:
    	如果捕获到该异常类型执行的代码
    

    Exception是所有程序异常类的父类。

  • 异常的 else

    try:
    	可能发生错误的代码
    except 异常类型:
    	如果捕获到该异常类型执行的代码
    else:
    	print('else是没有异常的时候执行的代码')
    
  • 异常的 finally

    try:
    	可能发生错误的代码
    except 异常类型:
    	如果捕获到该异常类型执行的代码
    else:
    	print('else是没有异常的时候执行的代码')
    finally:
    	print('finally是有无异常都要执行的代码')
    

示例:

try:
    f = open('test.txt', 'r')
except Exception :
    f = open('test.txt', 'w')
else:
    print('没有异常执行的代码')
finally:
    f.close()

4.2 自定义异常

Python中,抛出自定义异常的语法为raise异常类对象。

示例:密码长度不足,则报异常(用户输入密码,如果输入的长度不足5位,则报错,即抛出自定义异常,并捕获该异常)。

# 自定义异常类,继承 Exception
class ShortInputError(Exception):
    def __init__(self, length, min_len):
        self.length = length
        self.min_len = min_len

    # 设置抛出异常的描述信息
    def __str__(self):
        return f'你输入的长度是{self.length},不能少于{self.min_len}个字符'

def main():
    try:
        con = input('请输入密码:')
        if len(con) < 5:
            # 抛出异常类创建对象
            raise ShortInputError(len(con), 5)
    except Exception as result:
        print(result)
    else:
        print('密码已经输入完成')

main()

运行结果:
在这里插入图片描述


五、模块和包

python 模块是一个 python 文件,导入模块就是导入 pthon 文件。

5.1 导入模块

5.1.1 导入方式

  1. import 模块名
  2. from 模块名 import 功能1, 功能2, ...
  3. from 模块名 import *

示例:

# 方式一:
# import 模块名
# import 模块名1, 模块名2, ...  (不推荐)
# 调用功能:模块名.功能名()
import math
print(math.sqrt(3))  # 开平方计算

# 方式二:
# from 模块名 import 功能1, 功能2 ...;
# 功能调用:(不需要书写模块名.功能)
from math import sqrt
print(sqrt(9))

# 方式三:
# from 模块名 import *
from math import *
print(sqrt(9))

5.1.2 定义别名

  • 模块定义别名: import 模块名 as 别名

  • 功能定义别名:from 模块名 import 功能 as 别名

  • 注意: 定义别名,就不能用原来的模块和功能名字

    # 模块别名
    import time as tt
    tt.sleep(2)
    # time.sleep(2) # 报错
    print('hello')
    
    # 功能别名
    from time import sleep as sl
    sl(2)
    print('hello')
    

5.2 自定义模块

自定义模块 my_module.py:

def testA(a, b):
    print(a + b)

# 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行  testA(4, 4) 函数调用
# 只在自身模块时,系统变量 __name__ 是 __main__
if __name__ == '__main__':  # 用于测试 
    testA(4, 4) 

调用自定义模块:

import my_module

my_module.testA(2,3)  # 5

注意: 如果使用 from .. import ..from .. import * 导入多个模块的时候,且模块内有同名功能。当调用这个同名功能的时候,调用到的是 后导入的模块的功能


5.3 模块定位顺序

当导入一个模块,Python解析器对模块位置的搜索顺序是:

  1. 当前目录
  2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
  3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/pythonl/

示例:

# 现假设当前目录下存在自定义模块 random ,和 python 中的 random 模块名重复,且没有自定义 randint 方法
import random
num = random.randint(0, 5) # 报错 -- 先搜索当前目录,所以导入的模块是自定义的 random 模块
print(num)

拓展:

# 数据通过引用传递,因此变量可以覆盖模块
import time
print(time)

time = 1
print(time)  # 1

5.4 all 列表

如果模块文件中有 __all__ 变量,当使用 from xxx import * 导入时,只能导入这个列表中的元素

自定义模块 my_modeule2.py:

# 定义多个功能,把某个功能添加到 __all__
__all__ = ['testA']

def testA():
    print('testA函数')

def testB():
    print('testB函数')

测试代码:

from my_module_2 import *
testA()  # testA函数
# testB()  # 报错  -- testB没有在 all 列表中

5.5 包

如果一个文件夹中含有__init__.py 文件,那么这个文件夹就称之为包。

包是模块的一个集合,将模块以文件夹的方式集中在一起。

5.5.1 导包方式

  • 方式一:

    import 包名.模块名
    
    调用方式:包名.模块名.目标
    
  • 方式二:

    from 包名 import *
    
    调用方式:模块名.目标
    

    注意: 必须在 __init__.py 文件中添加 __all__ = [] ,控制允许导入的模块列表。


包结构:
在这里插入图片描述

方式一示例:

my_module1.py:

def info_print1():
    print('my_module1')

测试代码:

import mypackage.my_module1
mypackage.my_module1.info_print1()  # my_module1

方式二示例:

my_module2.py:

def info_print2():
    print('my_module2')

__init__.py:

__all__ = ['my_module1']

测试代码:

from mypackage import *  # 导入模块1、2
my_module1.info_print1()  # my_module1
my_module1.info_print2()  # my_module2

5.5.2 注意事项

方式一在不引入 all 列表的时候方法也可以正常使用,但 pycharm 不会提示。
在这里插入图片描述

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-02-06 13:47:28  更:2022-02-06 13:48:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 0:52:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码