python基础语法.py
""" 数据类型 """ # # # int # num1 = 1 # # float # num2 =1.1 # print(type(num1)) # print(type(num2)) # # # str ,字符串,特点:数据都带引号,单引、双引均可 # a = 'hello world' # print(type(a)) # b=True # boolean # print(type(b)) # # # list 列表 # c = [10,20,30] # print(type(c)) # # # tuple 元组 # d = (10,20,30) # print(type(d)) # # # set 集合 # e = {10,20,30} # print(type(e)) # # # dict 字典 键值对 # f = {'name':'Tom','age': 16} # print((type(f))) # """ # 1.准备数据 # 2.格式化符号输出数据 # """ # age =18 # name = 'TOM' # weight = 75.5 # stu_id = 1 # # print('今年我的年龄是%d岁') # # 1.今年我的年龄是x岁 # print('今年我的年龄是%d岁' % age) # # 2.我的名字是x # print('名字是%s' % name) # # 3.我的体重是x公斤 # # 75.500000 # print('体重是%f公斤' % weight) # # 75.50 # print('体重是%.2f公斤' % weight) # # 4.我的学号是x # print('我的学号是%d' % stu_id) # # 4.1 我的学号是001 # # %06d,表示输出的整数显示位数,不⾜以0补全,超出当前位数则原样输出 # print('我的学号是%03d' % stu_id) # stu_id2 = 1000 # print('我的学号是%03d' % stu_id2) # # 5.我的名字是x,今年x岁了 # print('名字是%s,今年%d岁了' % (name,age)) # print('名字是%s,今年%d岁了' % (name,age + 1)) # # 6.我的名字是x,今年x岁了,体重是x公斤,学号是x # print('名字是%s,今年%d岁了,体重是%f公斤,学号是%d' % (name, age,weight, stu_id)) # print('名字是%s,今年%d岁了,体重是%.2f公斤,学号是%06d' % (name, age,weight, stu_id)) # # ''' # 格式化字符串除了%s,还可以写为 f'{表达式}' # ''' # # 7.我的名字是x,今年x岁了,体重是x公斤 # print('我的名字是%s,今年%s岁了,体重是%s公斤' %(name,age,weight)) # # print(f'我的名字是{name},今年{age}岁了,体重是{weight}公斤') # print(f'我的名字是{name},今年{age+1}岁了,体重是{weight}公斤') # # # %s 与f'{}'区别; f代码量少;f更高效;开发多用f; f-格式化是python3.6新增的格式化方法 # ''' 转义字符 \n :换⾏。 \t :制表符,⼀个tab键(4个空格)的距离。 \ 反斜杠 ''' # # 两行 # print('hello') # print('world') # # print('hello\npython') # # 缩进4空格 # print('\tabcd') ''' print函数的结束符 想⼀想,为什么两个print会换⾏输出? 在Python中,print(), 默认⾃带 end="\n" 这个换⾏结束符,所以导致每两个 print 直接会换⾏ 展示,⽤户可以按需求更改结束符。 ''' # print('hello') # print('hello') # print('输出内容', end="\n") # print('输出内容', end=" ") # print('hello', end="....\t") # print('world', end=" ") ''' 1.书写input input('提示信息') 2.观察特点 输⼊的特点 当程序执⾏到 input ,等待⽤户输⼊,输⼊完成之后才继续向下执⾏。 在Python中, input 接收⽤户输⼊后,⼀般存储到变量,⽅便使⽤。 在Python中, input 会把接收到的任意⽤户输⼊的数据都当做字符串处理。 ''' # password = input('请输入您的密码:') # print(f'您输入的密码是{password}') # print(type(password)) ''' 转换数据类型 int(x [,base ]) 将x转换为⼀个整数 float(x ) 将x转换为⼀个浮点数 complex(real [,imag ]) 创建⼀个复数,real为实部,imag为虚部 str(x ) 将对象 x 转换为字符串 repr(x ) 将对象 x 转换为表达式字符串 eval(str ) ⽤来计算在字符串中的有效Python表达式,并返回⼀个对象 tuple(s ) 将序列 s 转换为⼀个元组 list(s ) 将序列 s 转换为⼀个列表 ''' # num = input('请输入数字:') # print(num,type(num)) # str # print(type(int(num))) # <class 'int'> # 1. float() -- 转换成浮点型 # num1 = 1 # print(float(num1)) # 1.0 # print(type(float(num1))) # str1 = '10' # print(float(str1)) #10.0 # # # 2. str() -- 转换成字符串类型 # num2 = 10 # print(type(str(num2))) # # # 3. tuple() -- 将⼀个序列转换成元组 # list1 = [10, 20, 30] # print(tuple(list1)) # (10, 20, 30) # # # 4. list() -- 将⼀个序列转换成列表 # t1 = (100, 200, 300) # print(list(t1)) # # # 5. eval() -- 将字符串中的数据转换成Python表达式原本类型 # str1 = '10' # str0 = '1.1' # str2 = '[1, 2, 3]' # str3 = '(1000, 2000, 3000)' # print(type(eval(str1))) # print(type(eval(str0))) # print(type(eval(str2))) # print(type(eval(str3))) ''' 运算符 运算符的分类: 算数运算符 赋值运算符 复合赋值运算符 ⽐较运算符 逻辑运算符 单击pycharm - python console ;打开 ''' ''' PyDev console: starting. Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32 1 + 1 2 1 + 1.1 2.1 1 - 1 0 1 - 0.5 0.5 2 * 0.5 1.0 4 / 2 2.0 2.0 9 // 4 2 9 % 4 1 2 ** 3 8 1 + 2 * 3 7 (1+2) * 3 9 2 * 3 ** 2 18 (2 * 3) ** 2 36 # # // 整除 9 // 4 输出结果为2 # # % 取余 9 % 4 输出结果为 1 # # ** 指数 2 ** 4 输出结果为 16,即 2 * 2 * 2 * 2 # # () ⼩括号 ⼩括号⽤来提⾼运算优先级,即 (1 + 2) * 3 输出结果为 9 # 混合运算优先级顺序: () ⾼于 ** ⾼于 * / // % ⾼于 + - tyhon console >>> # 多个变量赋值 num1, num2, str1 = 1, 1.1, 'abc' num1 1 # 多变量赋相同值 a = b = 100 a 100 b 100 ''' ''' 复合赋值运算符 ''' # c = 10 # # c = 10 + 1 + 2 # 错误 # # c += 3 -- c = c + 3 # 正确 (先算复合赋值运算符右边的表达式,再算复合运算符) # c += 1 + 2 # print(c) # 13 # # d = 10 # d *= 1 + 2 # print(d) # 30 ''' 比较运算符 1 == 1 True ''' ''' 逻辑运算符 and or not x and y x or y not x ''' # a = 1 # b = 2 # c = 3 # # print( (a < b) and ( b < c)) # print((a > b) or (c > b)) # print(not (b < c)) ''' 条件语句 if 条件: 条件成立执行的代码1 ..... ''' # if True: # if False: # print("条件成立执行的代码") # print("条件成立执行的代码") # # print('这个代码执行吗?') # age = int(input('请输入您的年龄:')) # if age >= 18 : # print(f"您已经成年{age}岁,可以上网") # D:\Learn\HM-21人工智能Ai\21年【年度钻石会员】人工智能AI进阶\阶段1 人工智能Python基础\第三章 判断语句\3-3 if...elif...else格式 ''' if 条件: 代码 else: 代码 ''' # age = int(input('请输入您的年龄:')) # if age > 18: # print('已经成年,可以上网') # else: # print('未成年,不可上网') ''' 多重判断 if 条件1: 代码1 elif 条件2: 代码2 else: 以上都不成立时,执行 ''' # age = int(input('请输入年龄:')) # # if age < 18: # print("为童工,不合法") # elif age >= 18 and age < 60: # print("合法工作年龄") # else: # print('退休了') ''' if嵌套 ''' """ 1. 如果有钱,则可以上⻋ 2. 上⻋后,如果有空座,可以坐下 上⻋后,如果没有空座,则站着等空座位 如果没钱,不能上⻋ """ # money = int(input('查找包里是否有钱:')) # if money > 1: # hasSit = False # if hasSit: # print('有空座,可坐下') # else: # print('无座,有钱也站着') # else: # print('没钱,不能坐公交,走路吧!') ''' 猜拳游戏 1. 导出random模块 2. 使⽤random模块中的随机整数功能 语法如下: 1 import 模块名 1 random.randint(开始,结束) ,包含开始和结束 ''' # import random # # player = int(input('0-石头,1-剪刀,2-布:')) # # computer = random.randint(0, 2) # print(computer) # # if (player == 0 and computer == 1) or (player == 1 and computer == 2) or (player == 2 and computer == 1): # print('玩家胜利') # elif (player == computer): # print('平局') # else: # print('玩家输') ''' 三⽬运算符 条件成⽴执⾏的表达式 if 条件 else 条件不成⽴执⾏的表达式 ''' # a = 1 # b = 2 # c = a if a > b else b # print(c) # # aa = 10 # bb = 6 # cc = (aa - bb) if (aa > bb) else (bb - aa) # print(cc) ''' while 条件: 条件成⽴重复执⾏的代码1 条件成⽴重复执⾏的代码2 ''' # 循环计数器,一般第一个计数值为从0开始; # i = 0 # while i < 5: # print('媳妇儿,我错了') # i += 1 ''' 0-100内偶数累加的和 ''' # 程序去计算偶数 # i = 2 # result = 0 # while i <= 100: # if (i % 2 == 0): # result += i # i += 1 # print(result) # 人为经验判断:偶数+2为偶数 # i = 2 # result = 0 # while i <= 100: # result += i # i += 2 # print(result) ''' break和continue是循环中满⾜⼀定条件退出循环的两种不同⽅式 ''' ''' 4.1 理解 举例:⼀共吃5个苹果,吃完第⼀个,吃第⼆个…,这⾥"吃苹果"的动作是不是重复执⾏? 情况⼀:如果吃的过程中,吃完第三个吃饱了,则不需要再吃第4个和第五个苹果,即是吃苹果的动作 停⽌,这⾥就是break控制循环流程,即终⽌此循环。 情况⼆:如果吃的过程中,吃到第三个吃出⼀个⼤⾍⼦...,是不是这个苹果就不吃了,开始吃第四个苹 果,这⾥就是continue控制循环流程,即退出当前⼀次循环继⽽执⾏下⼀次循环代码。 ''' # i = 1 # while i <= 5: # print(f'吃完第{i}个了') # if i == 3: # print(f'吃饱了') # break # i += 1 # # i = 1 # while i <= 5: # if i == 3: # print(f'吃到第{i}个,吃出一个大虫子,这个不吃了') # i += 1 # print(f'吃完第{i}个了') # i += 1 ''' while循环嵌套 ''' ''' 打印*形正方形 ''' # i = 0 # while i < 5: # print('', end='\n') # j = 0 # while j < 5: # print('*', end='') # j += 1 # i += 1 ''' 打印星号(三⻆形) ''' # i = 0 # while i < 5: # print('', end='\n') # j = 0 # while i >= j: # print('*', end='') # j += 1 # i += 1 ''' 九九乘法表 ''' # i = 1 # while i <= 9: # print('', end='\n') # j = 1 # while i >= j: # print(f'{i} x {j} = { i * j }', end='\t') # j += 1 # i += 1 ''' for循环 ''' ''' for 临时变量 in 序列: 重复执⾏的代码1 重复执⾏的代码2 ''' # str1 = 'itheima' # for i in str1: # print(i) ''' 循环可以和else配合使⽤,else下⽅缩进的代码指的是【当循环正常结束之后要执⾏的代码。】 break退出,则不执行else,continue,会执行else while、for都可与else配合使用 ''' ''' 需求:⼥朋友⽣⽓,要求道歉5遍:媳妇⼉,我错了。道歉到第三遍的时候,媳妇埋怨这⼀遍说的不真 诚,是不是就是要退出循环了?这个退出有两种可能性: 更⽣⽓,不打算原谅,也不需要道歉了,程序如何书写? 只⼀遍不真诚,可以忍受,继续下⼀遍道歉,程序如何书写? ''' # i = 1 # while i <= 5: # if i == 3: # print('这一遍不真诚;不打算原谅了;不需要道歉了') # break # print(f'媳妇儿,我道歉第{i}遍了') # i += 1 # else: # print('媳妇原谅我了') # # i = 1 # while i <= 5: # if i == 3: # print('这一遍不真诚;继续下一次道歉') # i += 1 # continue # print(f'媳妇儿,我道歉第{i}遍了') # i += 1 # else: # print('媳妇原谅我了') ''' 字符串 ''' # 单引号 代码显示效果换行了,内容以脚本的思想,没有换行 # a = 'hello ' \ # 'world' # print(a) # print(type(a)) # b = "TOM" # print(type(b)) # # # 三引号 支持内容回车换行原样输出展示 # e = '''i am TOM''' # print(type(e)) # f = """I AM # TOM""" # print(type(f)) # print(f) # # # I'm TOM # c = "I'm TOM" # print(c) # print(type(c)) # # # d = 'I'm TOM' # d = 'I\'m TOM' # print(d) ''' 下标 ''' # str1 = 'abcdefg' # print(str1) # print(str1[2]) # c # print(str1[5]) # f ''' 切⽚ 序列[开始位置下标:结束位置下标:步⻓] [ ) 左闭右开 ''' str1 = '012345678' # 得到整个字符串 # print(str1) # print(str1[2:5:1]) # 234 # print(str1[2:5:2]) # 24 # print(str1[2:5]) # 234 # print(str1[:5]) # 01234 不写开始,默认从0开始 # print(str1[2:]) # 2345678 不写结束,表示选取到末尾 # print(str1[:]) # 不写开始结束,表示选取从头到尾 # print(str1[::-1]) # 876543210 # 如果步长为负数,表示倒叙选取 # print(str1[-4:-1]) # 567 # 终极测试 # print(str1[-4:-1:1]) # 567 # print(str1[-4:-1:-1]) # 不能选取出数据 从-4开始到-1结束,选取方向从左到右;但是-1是从右向左选取;方向不一致 # # **** 如果选取方向(下标开始到结束)和步长的方向冲突,则无法选取数据 # print(str1[-1:-4:-1]) # 876 # D:\Learn\HM-21人工智能Ai\21年【年度钻石会员】人工智能AI进阶\阶段1 人工智能Python基础\第五章 字符串\5-4 字符串操作方法 ''' 四、常⽤操作⽅法 ''' ''' find():检测某个⼦串是否包含在这个字符串中,如果在返回这个⼦串开始的位置下标,否则则返回-1。 字符串序列.find(⼦串, 开始位置下标, 结束位置下标) 注意:开始和结束位置下标可以省略,表示在整个字符串序列中查找。 index():检测某个⼦串是否包含在这个字符串中,如果在返回这个⼦串开始的位置下标,否则则报异常。 ''' # mystr = "hello world and itcast and itheima and Python" # 1. find() # print(mystr.find('and')) # 12 # print(mystr.find('and', 15, 30)) # 23 # print(mystr.find('ands')) # 不存在,返回 -1 # 2. index() # print(mystr.index('and')) # print(mystr.index('ands')) # 不存在,报错: ValueError: substring not found # 3. count() # print(mystr.count('and', 15, 30)) # 1 # print(mystr.count('and')) # 3 ''' rfind(): 和find()功能相同,但查找⽅向为右侧开始。 rindex():和index()功能相同,但查找⽅向为右侧开始。 ''' # print(mystr.rfind('and')) # 35 # print(mystr.rfind('ands')) # -1 # print(mystr.rindex('and')) # 35 # print(mystr.rindex('ands')) # ValueError: substring not found ''' 修改 ''' ''' replace():替换; 有返回值,返回值是修改后的字符串;原字符串变量没有改变 字符串序列.replace(旧⼦串, 新⼦串, 替换次数) 注意:替换次数如果查出⼦串出现次数,则替换次数为该⼦串出现次数。 ''' # mystr = "hello world and itcast and itheima and Python" # 数据是否可以改变划分为可变类型和不可变类型 # new_str = mystr.replace('and', 'he') # print(new_str) # print(mystr.replace('and', 'he', 2)) # print(mystr.replace('and', 'he', 10)) ''' split():按照指定字符分割字符串。 分割,返回一个列表,丢失分割字符 字符串序列.split(分割字符, num) num表示的是分割字符出现的次数,即将来返回数据个数为num+1个。 ''' # list1 = mystr.split('and') # list1 = mystr.split('and', 2) # print(list1) ''' join() 合并列表里面的字符串数据为一个大字符串 ''' # mylist = ['aa', 'bb', 'cc'] # # aa..bb..cc # print('..'.join(mylist)) ''' 大小写转换 capitalize():将字符串第⼀个字符转换成⼤写。 capitalize()函数转换后,只字符串第⼀个字符⼤写,其他的字符全都⼩写。 title():将字符串每个单词⾸字⺟转换成⼤写 lower():将字符串中⼤写转⼩写。 upper():将字符串中⼩写转⼤写。 ''' # mystr = "hello world and itcast and itheima and Python" # # print(mystr.capitalize()) # Hello world and itcast and itheima and python # # print(mystr.title()) # Hello World And Itcast And Itheima And Python # print(mystr.upper()) # HELLO WORLD AND ITCAST AND ITHEIMA AND PYTHON # print(mystr.lower()) # hello world and itcast and itheima and python ''' lstrip():删除字符串左侧空⽩字符。 rstrip():删除字符串右侧空⽩字符。 strip():删除字符串两侧空⽩字符。 ''' # mystr = " hello world and itcast and itheima and Python " # print(mystr) # print(mystr.lstrip()) # print(mystr.rstrip()) # print(mystr.strip()) ''' ljust():返回⼀个原字符串左对⻬,并使⽤指定字符(默认空格)填充⾄对应⻓度 的新字符串。 字符串序列.ljust(⻓度, 填充字符) rjust():返回⼀个原字符串右对⻬,并使⽤指定字符(默认空格)填充⾄对应⻓度 的新字符串,语法和 ljust()相同。 center():返回⼀个原字符串居中对⻬,并使⽤指定字符(默认空格)填充⾄对应⻓度 的新字符串,语 法和ljust()相同。 python console Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32 mystr = 'hello' mystr 'hello' mystr.ljust(10) 'hello ' mystr.ljust(10, '.') 'hello.....' mystr.rjust(10) ' hello' mystr.rjust(10, '.') '.....hello' mystr.center(10) ' hello ' mystr.center(10, '.') '..hello...' ''' ''' 字符串判断 ''' # mystr = "hello world and itcast and itheima and Python" # print(mystr.startswith('hello')) # print(mystr.startswith('world', 6)) # print(mystr.endswith('Python')) ''' isalpha():如果字符串⾄少有⼀个字符并且所有字符都是字⺟则返回 True, 否则返回 False。 isdigit():如果字符串只包含数字则返回 True 否则返回 False。 isalnum():如果字符串⾄少有⼀个字符并且所有字符都是字⺟或数字则返 回 True,否则返回False。 isspace():如果字符串中只包含空⽩,则返回 True,否则返回 False。 ''' # print('hello'.isalpha()) # print('123'.isdigit()) # print('abc123'.isalnum()) # print("\t\n".isspace()) # print(' '.isspace()) # True ''' 列表 ''' ''' 下标 ''' # name_list = ['TOM', 'Lily', 'ROSE'] # print(name_list) # print(name_list[1]) ''' index():返回指定数据所在位置的下标 。注意:如果查找的数据不存在则报错。 count():统计指定数据在当前列表中出现的次数。 与字符使用方式一样 len():访问列表⻓度,即列表中数据的个数。 判断是否存在 in:判断指定数据在某个列表序列,如果在返回True,否则返回False not in:判断指定数据不在某个列表序列,如果不在返回True,否则返回False ''' # name_list = ['TOM', 'Lily', 'ROSE'] # print(name_list.index('TOM')) # print(name_list.index('TOMS')) # ValueError: 'TOMS' is not in list # print(name_list.count('Lily')) # print(name_list.count('Lilys')) # 0 # print(len(name_list)) # print('TOM' in name_list) # print('TOMS' in name_list) # print('TOMS' not in name_list) # print('TOM' not in name_list) ''' 需求:查找⽤户输⼊的名字是否已经存在。 ''' # name_list = ['TOM', 'Lily', 'ROSE'] # name = input('请输入您的名字:') # if name in name_list: # print(f'{name}已存在') # else: # print(f'{name}可用') ''' 增加 append():列表结尾追加数据。 列表序列.append(数据) ''' # name_list = ['TOM', 'Lily', 'ROSE'] # name_list.append('XiaoMing') ['TOM', 'Lily', 'ROSE','XiaoMing'] # print(name_list) # 列表是可变类型 # name_list.append([11,22]) # 追加整个序列到列表 ['TOM', 'Lily', 'ROSE', 11, 23] # print(name_list) ''' extend():列表结尾追加数据,如果数据是⼀个序列,则将这个序列的数据逐⼀添加到列表。 ''' # name_list.extend('xiaoming') # print(name_list) # ['TOM', 'Lily', 'ROSE', 'x', 'i', 'a', 'o', 'm', 'i', 'n', 'g'] # name_list.extend([11,23]) # print(name_list) # ['TOM', 'Lily', 'ROSE', 11, 23] ''' insert():指定位置新增数据。 列表序列.insert(位置下标, 数据) ''' # name_list.insert(1,'aa') # print(name_list) # ['TOM', 'aa', 'Lily', 'ROSE'] ''' 删除 del ⽬标 del() ''' # del name_list # print(name_list) # NameError: name 'name_list' is not defined # del name_list[0] # print(name_list) # ['Lily', 'ROSE'] ''' pop():删除指定下标的数据(默认为最后⼀个),并返回该数据。 列表序列.pop(下标) ''' # del_name = name_list.pop() # del_name = name_list.pop(1) # print(del_name) # print(name_list) ''' remove(数据) ''' # name_list.remove('ROSE') # print(name_list) # name_list.clear() # print(name_list) ''' 修改 ''' # name_list = ['TOM', 'Lily', 'ROSE'] # # 修改指定下标的数据 # name_list[0] = 'aaa' # print(name_list) # # # 逆序 reverse() # list1 = [1, 3, 2, 5, 4, 6] # list1.reverse() # print(list1) # [6, 4, 5, 2, 3, 1] # # # sort() 排序:升序(默认)和降序 # # list1.sort() # # list1.sort(reverse=False) # list1.sort(reverse=True) # print(list1) ''' 复制 ''' # name_list = ['TOM', 'Lily', 'ROSE'] # name_li2 = name_list.copy() # name_li2.reverse() # print(name_li2) # print(name_list) ''' 列表的循环遍历 ''' name_list = ['TOM', 'Lily', 'ROSE'] # i = 0 # while i < len(name_list): # print(name_list[i]) # i += 1 # for i in name_list: # print(i) # # TOM # # Lily # # ROSE # # for idx,val in enumerate(name_list): # print(idx,val) ''' 列表嵌套 ''' # name_list = [['TOM','Lily', 'Rose'], ['张三','李四', '王五'], ['小米','小花','小明']] # print(name_list) # print(name_list[0]) # print(name_list[0][1]) ''' 综合应⽤ -- 随机分配办公室 需求:有三个办公室,8位⽼师,8位⽼师随机分配到3个办公室 步骤 1.准备数据 8位老师,3个办公室 2.分配老师到办公室 随机分配 3.验证是否分配成功 办公室列表追加老师 ''' # import random # teachers = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] # offices = [[], [], []] # for name in teachers: # offidx = random.randint(0,2) # offices[offidx].append(name) # i = 1 # for office in offices: # print(f'办公室{i}人数为{len(office)}') # for name in office: # print(name) # i += 1 ''' 元组 元组的应⽤场景 ⼀个元组可以存储多个数据,元组内的数据是不能修改的。 ''' # t1 = (10, 20, 30) # print(type(t1)) # print(t1) # t2 = (10,) # print(type(t2)) # <class 'tuple'> # t3 = (10) # print(type(t3)) # <class 'int'> # t4 = ('aaa') # print(type(t4)) # <class 'str'> # t5 = ('aaa',) # print(type(t5)) # <class 'tuple'> ''' 元组的常⻅操作 元组数据不⽀持修改,只⽀持查找,具体如下: 按下标查找数据 index():查找某个数据,如果数据存在返回对应的下标,否则报错,语法和列表、字符串的index ⽅法相同。 count():统计某个数据在当前元组出现的次数。 len():统计元组中数据的个数。 ''' # t1 = ('aa', 'bb', 'cc', 'dd') # print(t1[0]) # print(t1.index('aa')) # print(t1.index('bbb')) # print(t1.count('aa')) # print(len(t1)) ''' 元组修改 但是如果元组⾥⾯有列表,修改列表⾥⾯的数据则是⽀持的,故⾃觉很重要。 ''' # t1[0] = 'aaa' # TypeError: 'tuple' object does not support item assignment # t2 = ('aa', 'bb', ['cc', 'dd']) # print(t2[2]) # t2[2][0] = 'TOM' # print(t2) # ('aa', 'bb', ['TOM', 'dd']) ''' 字典 字典的应⽤场景 思考1: 如果有多个数据,例如:'Tom', '男', 20,如何快速存储? 字典,字典⾥⾯的数据是以键值对形式出现,字典数据和数据顺序没有关系,即字典不⽀持下标, 后期⽆论数据如何变化,只需要按照对应的键的名字查找数据即可。 创建字典的语法: 字典特点: 符号为⼤括号 数据为键值对形式出现 各个键值对之间⽤逗号隔开 ''' # 有数据的字典 dict1 = {'name': 'TOM', 'age': 20, 'gender':' 男'} # print(dict1) # print(type(dict1)) # <class 'dict'> # # 空字典 # dict2 = {} # dict3 = dict() # print(type(dict2)) # print(type(dict3)) ''' 字典常⻅操作 ''' # 增 字典序列[key] = 值 # 注意:如果key存在则修改这个key对应的值;如果key不存在则新增此键值对。 # dict1 = {'name': 'TOM', 'age': 20, 'gender':' 男'} # dict1['id'] = 110 # print(dict1) # dict1['name'] = 'ROSE' # print(dict1) # 删 del() / del:删除字典或删除字典中指定键值对。 # del(dict1) # print(dict1) # NameError: name 'dict1' is not defined # del dict1['name'] # del dict1['names'] # KeyError: 'names' # dict1.clear() # {} # print(dict1) # 改 字典序列[key] = 值 # 注意:如果key存在则修改这个key对应的值 ;如果key不存在则新增此键值对 # dict1['id'] = 110 # print(dict1) ''' 查 key值查找 如果当前查找的key存在,则返回对应的值;否则则报错。 get() keys() values() items() ''' # print(dict1['name']) # print(dict1['name1']) # print(dict1['name1']) # dict1 = {'name': 'TOM', 'age': 20, 'gender':' 男'} # print(dict1.get('name')) # TOM # print(dict1.get('id')) # None # print(dict1.get('id','Lily')) # Lily # # 查找字典中所有的key,返回可迭代的对象 # print(dict1.keys()) # dict_keys(['name', 'age', 'gender']) # # print(dict1.values()) # dict_values(['TOM', 20, ' 男']) # # 查找字典中所有的键值对,返回可迭代对象,里面的对象是元组,元组数据1是key,2是value # print(dict1.items()) # dict_items([('name', 'TOM'), ('age', 20), ('gender', ' 男')]) ''' 字典遍历 ''' # dict1 = {'name': 'TOM', 'age': 20, 'gender':' 男'} # # for key in dict1.keys(): # # print(key) # # for v in dict1.values(): # # print(v) # # for item in dict1.items(): # print(item) # ('name', 'TOM') # # # 遍历字典的键值对,拆包 # for k,v in dict1.items(): # print(f'{k}={v}') ''' 集合 创建集合使⽤ {} 或 set() , 但是如果要创建空集合只能使⽤ set() ,因为 {} ⽤来创建空字典。 特点: 1. 集合可以去掉重复数据; 2. 集合数据是⽆序的,故不⽀持下标 ''' # s1 = {10, 20, 30, 40, 50} # print(s1) # {40, 10, 50, 20, 30} # s2 = {10, 20, 30, 40, 30, 40, 50} # print(s2) # s3 = set('abcdefg') # print(s3) # {'d', 'b', 'g', 'f', 'a', 'e', 'c'} # s4 = set() # print(type(s4)) # <class 'set'> # s5 = {} # print(type(s5)) # <class 'dict'> ''' 集合常⻅操作⽅法 增加数据 因为集合有去重功能,所以,当向集合内追加的数据是当前集合已有数据的话,则不进⾏任何操作。 add() update(), 追加的数据是序列。 ''' # 集合是可变类型 # s1 = {10, 20} # s1.add(100) # print(s1) # s1.add(100) # s1.add([10,20,30]) # TypeError: unhashable type: 'list' # s1.update([10, 50, 30]) # print(s1) # s1.update(60) # TypeError: 'int' object is not iterable ''' 删除数据 remove(),删除集合中的指定数据,如果数据不存在则报错。 discard(),删除集合中的指定数据,如果数据不存在也不会报错。 pop(),随机删除集合中的某个数据,并返回这个数据 ''' # s1 = {10, 20, 30, 40, 50} # s1.remove(10) # s1.remove(100) # KeyError: 100 # s1.discard(10) # s1.discard(10) # print(s1) # del_num = s1.pop() # print(del_num) # print(s1) ''' 查找数据 in:判断数据在集合序列 not in:判断数据不在集合序列 ''' # s1 = {10, 20, 30, 40, 50} # print(10 in s1) # print(10 not in s1) ''' 公共操作 运算符 运算符 描述 ⽀持的容器类型 + 合并 字符串、列表、元组 * 复制 字符串、列表、元组 in/not in 元素是否存在 字符串、列表、元组、字典 公共⽅法 容器类型转换 ''' # # 1. 字符串 # str1 = 'aa' # str2 = 'bb' # str3 = str1 + str2 # print(str3) # aabb # # 2. 列表 # list1 = [1, 2] # list2 = [10, 20] # list3 = list1 + list2 # print(list3) # [1, 2, 10, 20] # # 3. 元组 # t1 = (1, 2) # t2 = (10, 20) # t3 = t1 + t2 # print(t3) # (10, 20, 100, 200) # dict1 = {'name':'aa'} # dict2 = {'gender':'bb'} # dict3 = dict1 + dict2 # TypeError: unsupported operand type(s) for +: 'dict' and 'dict' # print(dict3) # # 1. 字符串 # print('-' * 10) # ---------- # # 2. 列表 # list1 = ['hello'] # print(list1 * 4) # ['hello', 'hello', 'hello', 'hello'] # # 3. 元组 # t1 = ('world',) # print(t1 * 4) # ('world', 'world', 'world', 'world') # 1. 字符串 # print('a' in 'abcd') # True # print('a' not in 'abcd') # False # # 2. 列表 # list1 = ['a', 'b', 'c', 'd'] # print('a' in list1) # True # print('a' not in list1) # False # # 3. 元组 # t1 = ('a', 'b', 'c', 'd') # print('aa' in t1) # False # print('aa' not in t1) # True # dict1 = {'name': 'TOM', 'age': 20, 'gender':' 男'} # print('name' in dict1.keys()) # print('TOM' in dict1.values()) ''' 公共⽅法 函数 描述 len() 计算容器中元素个数 del 或 del() 删除 max() 返回容器中元素最⼤值 min() 返回容器中元素最⼩值 range(start, end, step) ⽣成从start到end的数字,步⻓为 step,供for循环使⽤;range()⽣成的序列不包含end数字。 enumerate() 函数⽤于将⼀个可遍历的数据对象(如列表、元组或字符串)组合为⼀个索引序 列,同时列出数据和数据下标,⼀般⽤在 for 循环当中。 ''' # 1. 字符串 # str1 = 'abcdefg' # print(len(str1)) # 7 # # 2. 列表 # list1 = [10, 20, 30, 40] # print(len(list1)) # 4 # # 3. 元组 # t1 = (10, 20, 30, 40, 50) # print(len(t1)) # 5 # # 4. 集合 # s1 = {10, 20, 30} # print(len(s1)) # 3 # # 5. 字典 # dict1 = {'name': 'Rose', 'age': 18} # print(len(dict1)) # 2 # str1 = 'abcdef' # list1 = [10,20,30] # t1 = (10,20,30) # s1 = {10,20,30} # dict1 = {'name': 'TOM','age':17} # del str1 # # del list1 # del(list1[0]) # print(list1) # del dict1['name'] # print(dict1) # print(max(str1),min(str1)) # print(max(list1),min(list1)) # print(range(1, 10,1)) # range(1, 10) 返回可迭代对象 # # 左闭右开 # for i in range(1, 10, 1): # print(i) # 默认步长是1 # for i in range(1, 10): # print(i) # # 默认从0开始 # for i in range(10): # print(i) ''' enumerate(可遍历对象, start=0) start参数⽤来设置遍历数据的下标的起始值,默认为0。 ''' # list1 = ['a', 'b', 'c', 'd'] # for i in enumerate(list1): # print(i) # (1, 'b') ... (下标 数据) # start 修改下标起始值 # for i in enumerate(list1,start=1): # print(i) ''' 容器类型转换 tuple() list() set() ''' # list1 = [10, 20, 30, 40, 50, 20] # s1 = {100, 200, 300, 400, 500} # t1 = ('a', 'b', 'c', 'd', 'e') # # print(tuple(list1)) # print(tuple(s1)) # # print(list(s1)) # print(list(t1)) # print(set(list1)) # print(set(t1)) ''' 列表推导式 ⽤⼀个表达式创建⼀个有规律的列表或控制⼀个有规律列表。 ---- 列表推导式 字典推导式 集合推导式 ''' # 需求创建一个0-10的列表 # while实现..... # list1 = [] # i = 0 # while i < 10: # list1.append(i) # i += 1 # print(list1) # for实现..... # list1 = [] # for i in range(10): # list1.append(i) # print(list1) # 列表推导式实现 # list1 = [i for i in range(10)] # print(list1) # 带if的列表推导式 # 需求:创建0-10的偶数列表 # list1 = [ i for i in range(0,10,2)] # print(list1) # list0 = [] # for i in range(10): # if i % 2 == 0: # list0.append(i) # print(list0) # list2 = [i for i in range(10) if i % 2 == 0] # print(list2) # 多个for循环实现列表推导式 # 需求:创建列表如下: [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] # list1 = [] # for i in range(1,3): # for j in range(3): # list1.append((i,j)) # list2 = [(i, j) for i in range(1, 3) for j in range(3)] # print(list2) ''' 字典推导式 如何快速合并为⼀个字典? 答:字典推导式 字典推导式作⽤:快速合并列表为字典或提取字典中⽬标数据。 ''' # . 创建⼀个字典:字典key是1-5数字,value是这个数字的2次⽅。 # dict1 = {i: i**2 for i in range(1, 5)} # print(dict1) # 将两个列表合并为⼀个字典 # list1 = ['name', 'age','gender'] # list2 = ['Tom', 20, 'man'] # dict2 = { list1[i]: list2[i] for i in range(len(list1))} # print(dict2) # # 如果两个列表数据长度不同,len统计列表数据多的个数,会报错;统计少的,不会报错 # # # 提取字典中⽬标数据 # counts = {'MBP': 268, 'HP': 125, 'DELL': 201, 'Lenovo': 199, 'acer': 99} # count1 = {k: v for k,v in counts.items() if v > 200} # print(count1) ''' 集合推导式 ''' # 需求:创建⼀个集合,数据为下⽅列表的2次⽅。 # list1 = [1, 1, 2] # set1 = {i**2 for i in list1} # print(set1) # print(set1) #
''' 函数 函数就是将⼀段具有独⽴功能的代码块 整合到⼀个整体并命名,在需要的位置调⽤这个名称即可完成对应的需求。 函数在开发过程中,可以更⾼效的实现代码重⽤。 学习目标 函数的作⽤ 函数的使⽤步骤 函数的参数作⽤ 函数的返回值作⽤ 函数的说明⽂档 函数嵌套 函数的使⽤步骤 定义函数 def 函数名(参数): 代码1 代码2 ...... 调⽤函数 函数名(参数) 不同的需求,参数可有可⽆。 ''' # def sel_fun(): # print('显示余额') # print('存款') # print('取款') # # print('恭喜你登录成功') # sel_fun() # print('您的余额为1000元') # sel_fun() # print('您取出了300元') # sel_fun() # info_print() def info_print(): print('hello world') # 结论1 函数是先定义,后调用 # 2 如果没有调用函数,函数里面的代码不会执行 # .函数的参数作⽤ ''' 完成需求如下:⼀个函数完成两个数1和2的加法运算,如何书写程序? ''' # 定义函数 # def add_num1(): # result = 1 + 2 # print(result) # # 调⽤函数 # add_num1() # # # 函数的返回值作⽤ # def buy(): # return '烟' # # 使⽤变量保存函数返回值 # goods = buy() # print(goods) ''' 思考:定义⼀个函数后,程序员如何书写程序能够快速提示这个函数的作⽤? 函数的说明⽂档;注释 函数的说明⽂档也叫函数的⽂档说明。 语法 定义函数的说明⽂档 def 函数名(参数): """ 说明⽂档的位置 """ 代码 ...... 查看函数的说明⽂档 help(函数名) ''' # def add_num(a, b): # """求和函数""" # return a + b # # # print(add_num(10, 20)) # # help(add_num) ''' 变量作⽤域 ''' # def testA(): # a = 100 # print(1) # # testA() ''' 局部变量 # 所谓局部变量是定义在函数体内部的变量,即只在函数体内部⽣效。 局部变量的作⽤:在函数体内部,临时保存数据,即当函数调⽤完成后,则销毁局部变量。 ''' # print(a) # NameError: name 'a' is not defined # 全局变量 ''' 所谓全局变量,指的是在函数体内、外都能⽣效的变量。 ''' # # 定义全局变量a # a = 100 # def testA(): # print(a) # # 访问全局变量a,并打印变量a存储的数据 # testA() # # def testB(): # a = 200 # 在 testB 函数内部的 a = 200 中的变量a是不是在修改全局变量 a # print(a) # testA() # 100 # testB() # 200 # print(f'全局变量a = {a}') # 全局变量a = 100 # # # 如何在函数体内部修改全局变量 # def testC(): # global a # a = 200 # print(a) # testA() # 100 # testC() # 200 # print(f'全局变量a = {a}') # 全局变量a = 100 ''' 函数的返回值 ''' ''' 如果⼀个函数如些两个return (如下所示),程序如何执⾏? return a, b 写法,返回多个数据的时候,默认是元组类型。 return后⾯可以连接列表、元组或字典,以返回多个值。 ''' # def return_num(): # # return 1, 2 # (1, 2) # # return (1, 2) # # return [1, 2] # return {'name':'TOM' ,'age': 13} # result = return_num() # print(result) # (1, 2) ''' 函数的参数 ''' ''' 位置参数 位置参数:调⽤函数时根据函数定义的参数位置来传递参数。 传递和定义参数的顺序及个数必须⼀致。 ''' # def user_info(name, age, gender): # print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}') # # user_info('TOM', 20, '男') ''' 关键字参数 函数调⽤,通过“键=值”形式加以指定。可以让函数更加清晰、容易使⽤,同时也清除了参数的顺序需求。 ''' # def user_info(name, age, gender): # print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}') # # # user_info('Rose', age=10, gender='男') # user_info(age=20, name='TOM', gender='男') # user_info(age=20, name='TOM') # TypeError: user_info() missing 1 required positional argument: 'gender' # :函数调⽤时,如果有位置参数时,位置参数必须在关键字参数的前⾯,但关键字参数之间不存在 # 先后顺序。 ''' 缺省参数 缺省参数也叫默认参数,⽤于定义函数,为参数提供默认值,调⽤函数时可不传该默认参数的值(注 意:所有位置参数必须出现在默认参数前,包括函数定义和调⽤)。 ''' # def user_info(name, age, gender='男'): # print(f'您的名字是{name}, 年龄是{age}, 性别是{gender}') # # # user_info('TOM', 20) # user_info('Rose', 18, '⼥') ''' 不定⻓参数 不定⻓参数也叫可变参数。⽤于不确定调⽤的时候会传递多少个参数(不传参也可以)的场景。此时,可 ⽤包裹(packing)位置参数,或者包裹关键字参数,来进⾏参数传递,会显得⾮常⽅便。 ''' # 包裹位置传递 # def user_info(*args): # print(args) # # user_info('TOM') # user_info('TOM', 18) # 注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为⼀个元组(tuple),args是元组类型,这就是包裹位置传递。 # 包裹关键字传递 # def user_info(**kwargs): # print(kwargs) # # user_info(name='TOM',age=13, id=110) # {'name': 'TOM', 'age': 13, 'id': 110} # ⽆论是包裹位置传递还是包裹关键字传递,都是⼀个组包的过程。 ''' 拆包和交换变量值 ''' # 拆包 # 拆包:元组 # def return_num(): # return 100, 200 # # num1, num2 = return_num() # print(num1,num2) # # # 拆包:字典 # dict1 = {'name': 'TOM', 'age': 18} # # 对字典进⾏拆包,取出来的是字典的key # a, b = dict1 # print(a,b) # name age # print(dict1[a],dict1[b]) ''' 交换变量值 需求:有变量 a = 10 和 b = 20 ,交换两个变量的值。 ⽅法⼀ 借助第三变量存储数据。 ⽅法⼆ a, b = b, a ''' # c = 0 # a = 10 # b = 20 # c = 10 # a = b # b = c # print(a,b) # a,b = 10,20 # a, b = b, a # print(a,b) ''' 引⽤ 在python中,值是靠引⽤来传递来的。 我们可以⽤ id() id() 来判断两个变量是否为同⼀个值的引⽤。 我们可以将id值理解为那块内存的地址标 识。 ''' # 1. int类型 # a = 1 # b = a # print(b) # print(id(a)) # print(id(b)) # print(id(a) == id(b)) # True # 2. 列表 # aa = [10, 20] # bb = aa # print(id(aa) == id(bb)) # True # print(id(bb)) # aa.append(30) # print(id(aa) == id(bb)) # True # 引⽤当做实参 # def test1(a): # print(a) # print(id(a)) # a += a # print(a) # print(id(a)) # # b = 100 # 不可变类型,在函数内部数值变化时, a += a 导致函数内局部的a id 变化,新开空间; # test1(b) # # c = [11, 22] # 可变类型,在函数内部数据变化时, a += a id不会发生变化; # test1(c) ''' # 可变和不可变类型 所谓可变类型与不可变类型是指:数据能够直接进⾏修改,如果能直接修改那么就是可变,否则是不可变. 可变类型 列表 字典 集合 不可变类型 整型 浮点型 字符串 元组 ''' # info = [] # # def add(): # dict = {'name':'TOM', 'age': 23} # # global info # info.append(dict) # # print(info) # add() # print(info) ''' 递归 2.1 递归的应⽤场景 递归是⼀种编程思想,应⽤场景: 1. 在我们⽇常开发中,如果要遍历⼀个⽂件夹下⾯所有的⽂件,通常会使⽤递归来实现; 2. 在后续的算法课程中,很多算法都离不开递归,例如:快速排序。 ''' # def sum_num(num): # if num == 1: # return 1 # return num + sum_num(num-1) # # print(sum_num(996)) # 有最大递归深度 ''' lambda的应⽤场景 lambda语法 lambda 参数列表 : 表达式 注意 lambda表达式的参数可有可⽆,函数的参数在lambda表达式中完全适⽤。 lambda表达式能接收任何数量的参数但只能返回⼀个表达式的值。 ''' # def fn1(): # return 200 # # print(fn1) # <function fn1 at 0x000002B631295EE8> # print(fn1()) # 200 # # ⽆参数 # fn2 = lambda: 100 # print(fn2) # <function <lambda> at 0x0000017C60B3DEE8> # lambda的内存地址 # print(fn2()) # 100 # fn1 = lambda a, b: a + b # print(fn1(10,10)) # 默认参数 # fn1 = lambda a, b, c=100: a + b + c # print(fn1(10,20)) # .可变参数:*args # fn1 = lambda *args: args # print(fn1(10,20,30)) # (10, 20, 30) # 注意:这⾥的可变参数传⼊到lambda之后,返回值为元组。 # # fn1 = lambda **kwargs: kwargs # print(fn1(name='python',age = 20)) # {'name': 'python', 'age': 20} # 带判断的lambda # fn1 = lambda a, b: a if a > b else b # print(fn1(10,20)) # 列表数据按字典key的值排序 students = [ {'name': 'TOM', 'age': 20}, {'name': 'ROSE', 'age': 19}, {'name': 'Jack', 'age': 22} ] # # 按name值升序排列 # students.sort(key=lambda x: x['name']) # print(students) # # 按name值降序排列 # students.sort(key=lambda x: x['name'],reverse=True) # print(students) ''' . ⾼阶函数 把函数作为参数传⼊,这样的函数称为⾼阶函数,⾼阶函数是函数式编程的体现。函数式编程就是指这 种⾼度抽象的编程范式。 ''' # # 在Python中, abs() 函数可以完成对数字求绝对值计算。 # print(abs(-10)) # 10 # # round() 函数可以完成对数字的四舍五⼊计算 # print(round(1.2)) # print(round(1.9)) # #需求: 任意两个数字,按照指定要求整理数字后再进⾏求和计算。 # def sum_num(a, b): # return abs(a) + abs(b) # # print(sum_num(-10,-20)) # def sum_num(a, b, f): # return f(a) + f(b) # # print(sum_num(-10,-20,abs)) # 注意:两种⽅法对⽐之后,发现,⽅法2的代码会更加简洁,函数灵活性更⾼。 # 函数式编程⼤量使⽤函数,减少了代码的重复,因此程序⽐较短,开发速度较快。 ''' 内置⾼阶函数 map() map(func, lst),将传⼊的函数变量func作⽤到lst变量的每个元素中,并将结果组成新的列表(Python2)/迭代器(Python3)返回。 reduce(func,lst),其中func必须有两个参数。每次func计算的结果继续和序列的下⼀个元素做累积计算。 注意:reduce()传⼊的参数func必须接收2个参数。 filter() filter(func, lst)函数⽤于过滤序列, 过滤掉不符合条件的元素, 返回⼀个 filter 对象。如果要转换为列表, 可以使⽤ list() 来转换 ''' # # 需求:计算 list1 序列中各个数字的2次⽅。 # list1 = [1, 2, 3, 4, 5] # def func(x): # return x ** 2 # # result = map(func, list1) # print(result) # <map object at 0x000002963DFEBB08> # print(list(result)) # # for i in result: # print(i) # 需求:计算 list1 序列中各个数字的累加和。 # import functools # list1 = [1, 2, 3, 4, 5] # def func(a, b): # return a + b # # result = functools.reduce(func,list1) # print(result) # list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # def func(num): # return num % 2 == 0 # # result = filter(func,list1) # print(result) # <filter object at 0x000002455AC3BA48> # print(list(result)) ''' ⽂件操作 ⽂件操作的作⽤ ⽂件的基本操作 打开 读写 关闭 ⽂件备份 ⽂件和⽂件夹的操作 总结:⽂件操作的作⽤就是把⼀些内容(数据)存储存放起来,可以让程序下⼀次执⾏的时候直接使 ⽤,⽽不必重新制作⼀份,省时省⼒。 ''' ''' . ⽂件的基本操作 2.1 ⽂件操作步骤 1. 打开⽂件 2. 读写等操作 3. 关闭⽂件 注意:可以只打开和关闭⽂件,不进⾏任何读写操作。 2.1.1 打开 在python,使⽤open函数,可以打开⼀个已经存在的⽂件,或者创建⼀个新⽂件,语法如下: name:是要打开的⽬标⽂件名的字符串(可以包含⽂件所在的具体路径)。 mode:设置打开⽂件的模式(访问模式):只读、写⼊、追加等。 模 式 描述 r 以只读⽅式打开⽂件。⽂件的指针将会放在⽂件的开头。这是默认模式。 rb 以⼆进制格式打开⼀个⽂件⽤于只读。⽂件指针将会放在⽂件的开头。这是默认模式。 r+ 打开⼀个⽂件⽤于读写。⽂件指针将会放在⽂件的开头。 rb+ 以⼆进制格式打开⼀个⽂件⽤于读写。⽂件指针将会放在⽂件的开头。 w 打开⼀个⽂件只⽤于写⼊。如果该⽂件已存在则打开⽂件,并从开头开始编辑,即原有内 容会被删除。如果该⽂件不存在,创建新⽂件。 wb 以⼆进制格式打开⼀个⽂件只⽤于写⼊。如果该⽂件已存在则打开⽂件,并从开头开始编 辑,即原有内容会被删除。如果该⽂件不存在,创建新⽂件。 w+ 打开⼀个⽂件⽤于读写。如果该⽂件已存在则打开⽂件,并从开头开始编辑,即原有内容 会被删除。如果该⽂件不存在,创建新⽂件。 wb+ 以⼆进制格式打开⼀个⽂件⽤于读写。如果该⽂件已存在则打开⽂件,并从开头开始编 辑,即原有内容会被删除。如果该⽂件不存在,创建新⽂件。 a 打开⼀个⽂件⽤于追加。如果该⽂件已存在,⽂件指针将会放在⽂件的结尾。也就是说, 新的内容将会被写⼊到已有内容之后。如果该⽂件不存在,创建新⽂件进⾏写⼊。 ab 以⼆进制格式打开⼀个⽂件⽤于追加。如果该⽂件已存在,⽂件指针将会放在⽂件的结 尾。也就是说,新的内容将会被写⼊到已有内容之后。如果该⽂件不存在,创建新⽂件进 ⾏写⼊。 a+ 打开⼀个⽂件⽤于读写。如果该⽂件已存在,⽂件指针将会放在⽂件的结尾。⽂件打开时 会是追加模式。如果该⽂件不存在,创建新⽂件⽤于读写。 ab+ 以⼆进制格式打开⼀个⽂件⽤于追加。如果该⽂件已存在,⽂件指针将会放在⽂件的结 尾。如果该⽂件不存在,创建新⽂件⽤于读写。 ''' # f = open('test.txt','w') # f.write('aaa') # f.close() ''' 测试主访问模式 r w a (追加) ''' # r 如果文件不存在,报错,不支持写入操作;表示只读 # f = open('test1.txt', 'r') # f = open('test.txt', 'r') # # f.write('aa') # UnsupportedOperation: not writable # f.close() # w 只写,如果文件不存在,新建文件执行写入,会覆盖原有文件 # f = open('1.txt','w') # # f.write('aaa') # f.write('bbb') # f.close() # a 追加 如果文件不存爱,新建文件,在原有内容基础上,追加新内容 # f = open('2.txt', 'a') # # f.write('xyz') # f.write('abc') # f.close() # 访问模式参数可以省略,如果省略表示访问模式为r # f = open('11.txt') # f = open('1.txt') # f.close() ''' 读 read() num表示要从⽂件中读取的数据的⻓度(单位是字节),如果没有传⼊num,那么就表示读取⽂ 件中所有的数据。 readlines() readlines可以按照⾏的⽅式把整个⽂件中的内容进⾏⼀次性读取,并且返回的是⼀个列表,其中每⼀⾏ 的数据为⼀个元素。 readline() readline()⼀次读取⼀⾏内容。 seek() 作⽤:⽤来移动⽂件指针 ⽂件对象.seek(偏移量, 起始位置)起始位置: 0:⽂件开头 1:当前位置 2:⽂件结尾 ''' # f = open('test.txt', 'r') # print(f.read()) # aaaaaa # bbbbbb # cccccc # print(f.read(10)) # 数据有隐藏的换行符号 # aaaaaa # bbb # f.close() # f = open('test.txt', 'r') # content = f.readlines() # print(content) # ['aaaaaa\n', 'bbbbbb\n', 'cccccc'] # f.close() # f = open('test.txt', 'r') # print(f.readline()) # print(f.readline()) # f.close() ''' 访问模式 带b是二进制 带+是可读可写 文件指针按照主访问模式 r w a 初始设置 ''' ''' 1.测试 r+ w+ a+ 2.文件指针对数据读取的影响 ''' # r+ 没有该文件报错;文件指针在开头, # f = open('test1.txt', 'r+') # f = open('test.txt', 'r+') # w+ 没有改文件会新建文件,文件指针在开头,用新内容覆盖原内容 # f = open('test100.txt', 'w+') # a+ 没有该文件会新建文件,文件指针在结尾 # f = open('test200.txt', 'a+') # # con = f.read() # print(con) # f.write("ccc") # f.close() ''' ⽂件对象.seek(偏移量, 起始位置) 作⽤:⽤来移动⽂件指针。 起始位置: 0:⽂件开头 1:当前位置 2:⽂件结尾 ''' # f = open('test.txt', 'r+') # # f.seek(5, 0) # 改变读取数据开始位置 # f.seek(0, 2) # 改为指针位置为结尾,读不出数据 # con = f.read() # print(con) # # f.close() ''' ⽂件备份 需求:⽤户输⼊当前⽬录下任意⽂件名,程序完成对该⽂件的备份功能(备份⽂件名为xx[备份]后缀,例 如:test[备份].txt)。 ''' ''' 1. 接收⽤户输⼊的⽂件名 2. 规划备份⽂件名 3. 备份⽂件写⼊数据 ''' # old_name = input('请输入您要被封的文件名:') # # index = old_name.rfind('.') # # new_name = old_name[:index] + '[备份]' + old_name[index:] # print(new_name) # # f = open(old_name,'rb') # f_bak = open(new_name,'wb') # # while True: # con = f.read(1024) # if len(con) == 0: # break # f_bak.write(con) # # f.close() # f_bak.close() ''' ⽂件和⽂件夹的操作 导⼊os模块 使⽤ os 模块相关功能 os.函数名() ''' import os # os.rename('1.txt','10.txt') # os.remove('10.txt') # 创建⽂件夹 # os.mkdir('aa') # 删除⽂件夹 # os.rmdir('aa') # 获取当前文件所在目录路径 # print(os.getcwd()) # 改变目录路径 # os.mkdir('aa') # os.mkdir('bb') # os.chdir('aa') # os.mkdir('bb') # 获取⽬录列表 # print(os.listdir()) ''' 需求1.:批量修改⽂件名,既可添加指定字符串,⼜能删除指定字符串。 1.找到所有文件-- listdir 2.构造名字 3.重命名 需求2. 删除Python_, 重命名:1,删除:2 ''' # import os # # os.chdir('aa') # # flag = int(input('请输入操作1:重命名,2:删除')) # print(flag) # file_list = os.listdir() # # for i in file_list: # if flag == 1: # new_name = 'Python_' + i # os.rename(i, new_name) # elif flag == 2: # num = len('Python_') # new_name = i[num:] # os.rename(i, new_name) # # print(os.listdir())
''' ⾯向对象基础 ⽬标 理解⾯向对象 类和对象 添加和获取对象属性 魔法⽅法 ''' ''' 类和对象 类和对象的关系:⽤类去创建⼀个对象。 ''' ''' 注意:类名要满⾜标识符命名规则,同时遵循⼤驼峰命名习惯。 2.2.1 定义类 Python2中类分为:经典类 和 新式类 语法 注意:类名要满⾜标识符命名规则,同时遵循⼤驼峰命名习惯。 class 类名(): 代码 ...... 拓展:经典类 不由任意内置类型派⽣出的类,称之为经典类 class 类名: 代码 ...... 创建对象 对象名 = 类名() ''' # class Washer(): # def wash(self): # print('能洗衣服') # print(self) # <__main__.Washer object at 0x00000205B8B5F0C8> # # haier = Washer() # # print(haier) # 打印出内存地址 <__main__.Washer object at 0x000001C522C08208> # haier.wash() ''' self指的是调⽤该函数的对象。 注意:打印对象和self得到的结果是⼀致的,都是当前对象的内存中存储地址。 ''' ''' 添加和获取对象属性 ''' ''' 类外⾯添加对象属性 对象名.属性名 = 值 ''' # class Washer(): # def wash(self): # print('能洗衣服') # # haier1 = Washer() # haier1.width = 400 # # ''' # 类外⾯获取对象属性 # ''' # print(haier1.width) ''' 类⾥⾯获取对象属性 self.属性名 ''' # class Washer(): # def wash(self): # print('能洗衣服') # # def print_info(self): # print(self.width) # # haier1 = Washer() # haier1.width = 400 # # haier1.print_info() ''' 魔法⽅法 在Python中, __xx__() 的函数叫做魔法⽅法,指的是具有特殊功能的函数。 ''' ''' 体验__init__() __init__() 思考:洗⾐机的宽度⾼度是与⽣俱来的属性,可不可以在⽣产过程中就赋予这些属性呢? 答:理应如此。 __init__() ⽅法的作⽤:初始化对象。 __init__() ⽅法,在创建⼀个对象时默认被调⽤,不需要⼿动调⽤ __init__(self) 中的self参数,不需要开发者传递,python解释器会⾃动把当前的对象引 ⽤传递过去。 ''' # class Washer(): # def __init__(self): # self.width = 500 # self.height = 800 # # def print_info(self): # print(self.width) # # haier = Washer() # haier.print_info() ''' 带参数的__init__() __init__() ''' # class Washer(): # def __init__(self, width, height): # self.width = width # self.height = height # # def print_info(self): # print(self.width) # # haier = Washer(10,20) # haier.print_info() ''' __str__() 当使⽤print输出对象的时候,默认打印对象的内存地址。如果类定义了 __str__ ⽅法,那么就会打印从 在这个⽅法中 return 的数据。 ''' # class Washer(): # def __init__(self, width, height): # self.width = width # self.height = height # def __str__(self): # return '这是海尔' # # h = Washer(10,20) # print(h) # 这是海尔 ''' __del__() 当删除对象时,python解释器也会默认调⽤ __del__() ⽅法。 ''' # class Washer(): # def __init__(self, width, height): # self.width = width # self.height = height # def __del__(self): # print(f'{self}对象已经被删除') # # h = Washer(10,20) # del h # <__main__.Washer object at 0x00000242D5DCF648>对象已经被删除 ''' 拓展1:经典类或旧式类 不由任意内置类型派⽣出的类,称之为经典类。 class 类名: 代码 ...... 拓展2:新式类 class 类名(object): 代码 ''' ''' ⾯向对象-继承 ⽬标 继承的概念 单继承 多继承 ⼦类重写⽗类的同名属性和⽅法 ⼦类调⽤⽗类的同名属性和⽅法 多层继承 super() 私有属性和私有⽅法 ''' ''' Python⾯向对象的继承指的是多个类之间的所属关系,即⼦类默认继承⽗类的所有属性和⽅法, ''' # class A(object): # def __init__(self): # self.num = 1 # # def info_print(self): # print(self.num) # # class B(A): # pass # # b = B() # b.info_print() # 在Python中,所有类默认继承object类,object类是顶级类或基类;其他⼦类叫做派⽣类。 ''' 单继承 故事主线:⼀个煎饼果⼦⽼师傅,在煎饼果⼦界摸爬滚打多年,研发了⼀套精湛的摊煎饼果⼦的 技术。师⽗要把这套技术传授给他的唯⼀的最得意的徒弟。 ''' # # 1. 师⽗类 # class Master(object): # def __init__(self): # self.kongfu = '[古法煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # # 2. 徒弟类 # class Prentice(Master): # pass # # # 3. 创建对象daqiu # daqiu = Prentice() # # 4. 对象访问实例属性 # print(daqiu.kongfu) ''' 多继承 故事推进:daqiu是个爱学习的好孩⼦,想学习更多的煎饼果⼦技术,于是,在百度搜索到⿊⻢程 序员,报班学习煎饼果⼦技术。 所谓多继承意思就是⼀个类同时继承了多个⽗类。 ''' # class Master(object): # def __init__(self): # self.kongfu = '[古法煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # # 创建学校类 # class School(object): # def __init__(self): # self.kongfu = '[⿊⻢煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # class Prentice(School, Master): # pass # # # daqiu = Prentice() # print(daqiu.kongfu) # daqiu.make_cake() # 注意:当⼀个类有多个⽗类的时候,默认使⽤第⼀个⽗类的同名属性和⽅法。 # ⼦类重写⽗类同名⽅法和属性 ''' 故事:daqiu掌握了师⽗和培训的技术后,⾃⼰潜⼼钻研出⾃⼰的独⻔配⽅的⼀套全新的煎饼果⼦ 技术。 ⼦类和⽗类具有同名属性和⽅法,默认使⽤⼦类的同名属性和⽅法。 ''' # class Master(object): # def __init__(self): # self.kongfu = '[古法煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # class School(object): # def __init__(self): # self.kongfu = '[⿊⻢煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # # 独创配⽅ # class Prentice(School, Master): # def __init__(self): # self.kongfu = '[独创煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # daqiu = Prentice() # print(daqiu.kongfu) # daqiu.make_cake() # # # (<class '__main__.Prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>) # # 打印一个雷的继承层级关系 # print(Prentice.__mro__) ''' ⼦类调⽤⽗类的同名⽅法和属性 故事:很多顾客都希望也能吃到古法和⿊⻢的技术的煎饼果⼦。 ''' # class Master(object): # def __init__(self): # self.kongfu = '[古法煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # class School(object): # def __init__(self): # self.kongfu = '[⿊⻢煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # class Prentice(School, Master): # def __init__(self): # self.kongfu = '[独创煎饼果⼦配⽅]' # # # 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化 # def make_cake(self): # self.__init__() # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # 调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化 # def make_master_cake(self): # Master.__init__(self) # Master.make_cake(self) # # def make_school_cake(self): # School.__init__(self) # School.make_cake(self) # # daqiu = Prentice() # daqiu.make_cake() # daqiu.make_master_cake() # daqiu.make_school_cake() # daqiu.make_cake() ''' 多层继承 故事:N年后,daqiu⽼了,想要把所有技术传承给⾃⼰的徒弟。 ''' # class Master(object): # def __init__(self): # self.kongfu = '[古法煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # class School(object): # def __init__(self): # self.kongfu = '[⿊⻢煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # class Prentice(School, Master): # def __init__(self): # self.kongfu = '[独创煎饼果⼦配⽅]' # # # 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化 # def make_cake(self): # self.__init__() # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # 调⽤⽗类⽅法,但是为保证调⽤到的也是⽗类的属性,必须在调⽤⽅法前调⽤⽗类的初始化 # def make_master_cake(self): # Master.__init__(self) # Master.make_cake(self) # # def make_school_cake(self): # School.__init__(self) # School.make_cake(self) # # class Tusun(Prentice): # pass # # xiaoqiu = Tusun() # xiaoqiu.make_cake() # xiaoqiu.make_master_cake() # xiaoqiu.make_school_cake() ''' super()调⽤⽗类⽅法 ''' # class Master(object): # def __init__(self): # self.kongfu = '[古法煎饼果⼦配⽅]' # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # class School(Master): # def __init__(self): # self.kongfu = '[⿊⻢煎饼果⼦配⽅]' # # def make_cake(self): # super(School, self).__init__() # super(School, self).make_cake() # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # class Prentice(School): # def __init__(self): # self.kongfu = '[独创煎饼果⼦配⽅]' # # # 如果是先调⽤了⽗类的属性和⽅法,⽗类属性会覆盖⼦类属性,故在调⽤属性前,先调⽤⾃⼰⼦类的初始化 # def make_cake(self): # self.__init__() # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # 需求 一次性调用父类School Master的方法 # def make_old_cake(self): # # 方法一: 如果定义的类名修改,这里也要修改,麻烦代码庞大,冗余 # # Master.__init__(self) # # Master.make_cake(self) # # School.__init__(self) # # School.make_cake(self) # # # 方法2 # # 2.1 super带参数 # # super(Prentice,self).__init__() # # super(Prentice, self).make_cake() # # # 2.2 super带参数 # super().__init__() # super().make_cake() # 注意:使⽤super() 可以⾃动查找⽗类。调⽤顺序遵循 __mro__ 类属性的顺序。⽐较适合单继承使⽤。 # # daqiu = Prentice() # daqiu.make_old_cake() ''' 私有权限 定义私有属性和⽅法 在Python中,可以为实例属性和⽅法设置私有权限,即设置某个实例属性或实例⽅法不继承给⼦类。 故事:daqiu把技术传承给徒弟的同时,不想把⾃⼰的钱(2000000个亿)继承给徒弟,这个时候就 要为 钱 这个实例属性设置私有权限。 设置私有权限的⽅法:在属性名和⽅法名 前⾯ 加上两个下划线 __。 ''' class School(object): def __init__(self): self.kongfu = '[⿊⻢煎饼果⼦配⽅]' # 定义私有属性 self.__money = 20000 def make_cake(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') def __print_info(self): print(f'运⽤{self.kongfu}制作煎饼果⼦') class Prentice(School): pass p = Prentice() # print(p.money) # # AttributeError: 'Prentice' object has no attribute 'money' # print(p.__money) # AttributeError: 'Prentice' object has no attribute '__money' # p.print_info() # p.__print_info() # 注意:私有属性和私有⽅法只能在类⾥⾯访问和修改。 ''' 获取和修改私有属性值 在Python中,⼀般定义函数名 get_xx ⽤来获取私有属性,定义 set_xx ⽤来修改私有属性值。 ''' # class School(object): # def __init__(self): # self.kongfu = '[⿊⻢煎饼果⼦配⽅]' # # 定义私有属性 # self.__money = 20000 # # # get set 是工作习惯 # def get_money(self): # return self.__money # # def set_money(self, money): # self.__money = money # # def make_cake(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # def __print_info(self): # print(f'运⽤{self.kongfu}制作煎饼果⼦') # # # class Prentice(School): # pass # # # p = Prentice() # print(p.get_money()) # p.set_money(10) # print(p.get_money()) ''' 多态 多态指的是⼀类事物有多种形态,(⼀个抽象类有多个⼦类,因⽽多态的概念依赖于继承)。 定义:多态是⼀种使⽤对象的⽅式,⼦类重写⽗类⽅法,调⽤不同⼦类对象的相同⽗类⽅法,可以 产⽣不同的执⾏结果 ''' # 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() # # daqiu = Person() # daqiu.work_with_dog(ad) # daqiu.work_with_dog(dd) ''' 类属性和实例属性 ''' ''' 类属性 设置和访问类属性 类属性就是 类对象 所拥有的属性,它被 该类的所有实例对象 所共有。 类属性可以使⽤ 类对象 或 实例对象 访问。 类属性的优点 记录的某项数据 始终保持⼀致时,则定义类属性。 实例属性 要求 每个对象 为其 单独开辟⼀份内存空间 来记录数据,⽽ 类属性 为全类所共有 ,仅占⽤⼀份内存,更加节省内存空间。 ''' # class Dog(object): # tooth = 10 # # wangcai = Dog() # xiaohei = Dog() # # # # print(Dog.tooth) # 10 # # print(wangcai.tooth) # 10 # # print(xiaohei.tooth) # 10 # # ''' # 修改类属性 # 类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建了 # ⼀个实例属性。 # ''' # # Dog.tooth = 12 # # 不能通过对象修改属性,如果这样操作,实则是创建了⼀个实例属性 # wangcai.tooth = 20 # print(Dog.tooth) # 12 # print(wangcai.tooth) # 20 # print(xiaohei.tooth) # 12 ''' 实例属性 ''' # class Dog(object): # def __init__(self): # self.age = 5 # # def info_print(self): # print(self.age) # # # wangcai = Dog() # print(wangcai.age) # 5 # # print(Dog.age) # 报错:实例属性不能通过类访问 # wangcai.info_print() # 5 ''' 类⽅法和静态⽅法 类⽅法特点 需要⽤装饰器 @classmethod 来标识其为类⽅法,对于类⽅法,第⼀个参数必须是类对象,⼀般以 cls 作为第⼀个参数。 类⽅法使⽤场景 当⽅法中 需要使⽤类对象 (如访问私有类属性等)时,定义类⽅法 类⽅法⼀般和类属性配合使⽤ ''' # class Dog(object): # __tooth = 10 # # @classmethod # def get_tooth(cls): # return cls.__tooth # # # wangcai = Dog() # result = wangcai.get_tooth() # print(result) # 10 ''' 静态⽅法 静态⽅法特点 需要通过装饰器 @staticmethod 来进⾏修饰,静态⽅法既不需要传递类对象也不需要传递实例对象 (形参没有self/cls)。 静态⽅法 也能够通过 实例对象 和 类对象 去访问。 静态⽅法使⽤场景 当⽅法中 既不需要使⽤实例对象(如实例对象,实例属性),也不需要使⽤类对象 (如类属性、类⽅ 法、创建实例等)时,定义静态⽅法 取消不需要的参数传递,有利于 减少不必要的内存占⽤和性能消耗 ''' # class Dog(object): # @staticmethod # def info_print(): # print('这是⼀个狗类,⽤于创建狗实例....') # # # wangcai = Dog() # # 静态⽅法既可以使⽤对象访问⼜可以使⽤类访问 # wangcai.info_print() # Dog.info_print() ''' 异常 ⽬标 了解异常 捕获异常 异常的else 异常finally 异常的传递 ⾃定义异常 ''' ''' 了解异常 当检测到⼀个错误时,解释器就⽆法继续执⾏了,反⽽出现了⼀些错误的提示,这就是所谓的"异常"。 异常的写法 语法 try: 可能发⽣错误的代码 except: 如果出现异常执⾏的代码 ''' ''' 快速体验 需求:尝试以 r 模式打开⽂件,如果⽂件不存在,则以 w ⽅式打开。 ''' # f = open('testa.txt', 'r') # try: # f = open('testa.txt','r') # except: # f = open('testa.txt','w') ''' 捕获指定异常 语法 try: 可能发⽣错误的代码 except 异常类型: 如果捕获到该异常类型执⾏的代码 注意: 1. 如果尝试执⾏的代码的异常类型和要捕获的异常类型不⼀致,则⽆法捕获异常。 2. ⼀般try下⽅只放⼀⾏尝试执⾏的代码。 ''' # print(num) # NameError: name 'num' is not defined # print(1/0) # ZeroDivisionError: division by zero # try: # print(num) # except NameError: # print('有错误') ''' 捕获多个指定异常 当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使⽤元组的⽅式进⾏书写。 ''' # try: # print(1/0) # except (NameError, ZeroDivisionError): # print('有错误') # 捕获异常描述信息 # try: # print(1/0) # except (NameError, ZeroDivisionError) as result: # print(result) ''' 捕获所有异常 Exception是所有程序异常类的⽗类。 ''' # try: # print(num) # except Exception as result: # print(result) ''' 异常的else else表示的是如果没有异常要执⾏的代码。 ''' # try: # print(1) # except Exception as result: # print(result) # else: # print('我是else,是没有异常时候执行的代码') ''' 异常的finally finally表示的是⽆论是否异常都要执⾏的代码,例如关闭⽂件。 ''' # try: # f = open('testa.txt', 'r') # except Exception as result: # f = open('testa.txt', 'w') # else: # print('没有异常,真开⼼') # finally: # f.close() # # print(f) #<_io.TextIOWrapper name='testa.txt' mode='r' encoding='cp936'> ''' 命令提示符下运行python文件 C:\Workspace\python00\pythonbase>python 09.py hello world ''' ''' 异常的传递 体验异常传递 需求: 1. 尝试只读⽅式打开test.txt⽂件,如果⽂件存在则读取⽂件内容,⽂件不存在则提示⽤户即可。 2. 读取内容要求:尝试循环读取内容,读取过程中如果检测到⽤户意外终⽌程序,则 except 捕获异常 并提示⽤户。 ''' ''' 如下代码在命令行下测试最好 ''' # import time # # try: # f = open('test.txt') # 默认以只读 # try: # while True: # con = f.readline() # if len(con) == 0: # break # print(con) # time.sleep(2) # except: # # 在命令行下ctrl + c 属于异常终止 # print('程序意外终止') # ''' # C:\Workspace\python00\pythonbase>python 面向对象和异常.py # aaaaa # 程序以外终止 # ''' # except: # print('文件不存在') ''' ⾃定义异常 在Python中,抛出⾃定义异常的语法为 raise 异常类对象 。 需求:密码⻓度不⾜,则报异常(⽤户输⼊密码,如果输⼊的⻓度不⾜3位,则报错,即抛出⾃定义异 常,并捕获该异常)。 ''' ''' 1.自定义异常类 2.抛出异常 3.捕获异常 ''' # ⾃定义异常类,继承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: password = input('请输入密码:') if len(password) < 3: raise ShortInputError(len(password),3) except Exception as result: print(result) else: print('密码已经输入完成') main()
''' 模块和包 ⽬标 了解模块 导⼊模块 制作模块 __all__ 包的使⽤⽅法 Python 模块(Module),是⼀个 Python ⽂件,以 .py 结尾,包含了 Python 对象定义和Python语句。 模块能定义函数,类和变量,模块⾥也能包含可执⾏的代码。 ''' # import my_module1 ''' 导⼊模块 导⼊模块的⽅式 import 模块名 from 模块名 import 功能名 from 模块名 import * import 模块名 as 别名 from 模块名 import 功能名 as 别名 ''' ''' 导⼊⽅式详解 import # 1. 导⼊模块 import 模块名 推荐一个一个导入 import 模块名1, 模块名2... 不推荐如此导入多个 # 2. 调⽤功能 模块名.功能名() ''' # math sqrt 开平方 # import math # print(math.sqrt(9)) # 3.0 python 中类似于除法计算都会以浮点型返回 # from math import sqrt # print(sqrt(9)) # from math import * # print(sqrt(9)) # as定义别名 # import math as mymath # print(mymath.sqrt(9)) # from math import sqrt as mysqrt # print(mysqrt(9)) # # 模块别名 # import time as tt # tt.sleep(2) # print('hello') # # 功能别名 # from time import sleep as sl # sl(2) # print('hello') ''' 制作模块 在Python中,每个Python⽂件都可以作为⼀个模块,模块的名字就是⽂件的名字。也就是说⾃定义模 块名必须要符合标识符命名规则。 ''' ''' 步骤 定义模块 新建⼀个Python⽂件,命名为 my_module1.py ,并定义 testA 函数。 测试模块 在实际开中,当⼀个开发⼈员编写完⼀个模块后,为了让模块能够在项⽬中达到想要的效果,这个开发 ⼈员会⾃⾏在py⽂件中添加⼀些测试信息.,例如,在 my_module1.py ⽂件中添加测试代码。 调⽤模块 ''' ''' def testA(a, b): print( a + b) # 测试信息,避免被引入其他模块而运行 if __name__ == '__main__': testA(3, 4) # __name__ 是系统变量 # print(__name__) # 在当前py文件中运行时,__name__ = __main__;当其他文件调用时 为模块名:my_module1''' # import my_module1 # my_module1.testA(1, 3) ''' 模块定位顺序s 当导⼊⼀个模块,Python解析器对模块位置的搜索顺序是: 1. 当前⽬录 2. 如果不在当前⽬录,Python则搜索在shell变量PYTHONPATH下的每个⽬录。 3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径⼀般为/usr/local/lib/python/ 模块搜索路径存储在system模块的sys.path变量中。变量⾥包含当前⽬录,PYTHONPATH和由安装过 程决定的默认⽬录。 注意 ⾃⼰的⽂件名不要和已有模块名重复,否则导致模块功能⽆法使⽤ 使⽤from 模块名 import 功能 的时候,如果功能名字重复,调⽤到的是最后定义或导⼊的功能。 ''' ''' 编写random.py ''' # import random # num = random.randint(0,10) # print(num) # # def sleep(): # # print('我是自定义的sleep') # # from time import sleep # # def sleep(): # print('我是自定义的sleep') # # sleep(2) # 名字重复的麻烦: # 问题: import 模块名 是否担心 功能名字重复的问题 -- 不需要担心 模块.方法 区别 # import time # print(time) # # time = 1 # print(time) # 问题 为什么变量也能覆盖模块 -- 在python语言中,数据是通过引用 传递 ''' __all__ __all__ 如果⼀个模块⽂件中有 __all__ 变量,当使⽤ from xxx import * 导⼊时,只能导⼊这个列表中的元 素。 ''' # from my_module1 import * # # testA(1,4) # # testB(1,4) # 因为testB不在all列表中 NameError: name 'testB' is not defined ''' __all__ = ['testA'] def testA(a, b): print( a + b) print('testA') def testB(a, b): print( a + b) print('testB') # 测试信息 if __name__ == '__main__': testA(3, 4) # __name__ 是系统变量 # print(__name__) # 在当前py文件中运行时,__name__ = __main__;当其他文件调用时 为模块名:my_module1 ''' ''' 包 包将有联系的模块组织在⼀起,即放到同⼀个⽂件夹下,并且在这个⽂件夹创建⼀个名字 为 __init__.py ⽂件,那么这个⽂件夹就称之为包。 ''' ''' 制作包 [New] — [Python Package] — 输⼊包名 — [OK] — 新建功能模块(有联系的模块)。 注意:新建包后,包内部会⾃动创建 __init__.py ⽂件,这个⽂件控制着包的导⼊⾏为。 ''' ''' 快速体验 1. 新建包 mypackage 2. 新建包内模块: my_module1 和 my_module2 3. 模块内代码如下 ''' ''' 导⼊包 2.2.1 ⽅法⼀ import 包名.模块名 包名.模块名.⽬标 ''' # import mypackage.my_module2 # mypackage.my_module2.info_print() ''' ⽅法⼆ 注意:必须在 __init__.py ⽂件中添加 __all__ = [] ,控制允许导⼊的模块列表。 from 包名 import * 模块名.⽬标 ''' from mypackage import * # my_module2.info_print() # 注释 __init__后 NameError: name 'my_module2' is not defined ''' __dict__ 收集类对象和实例对象的属性字典 ''' # 1. 定义类 class A(object): a = 0 def __init__(self): self.b = 1 # 2. 创建对象 aa = A() # 3. 调用__dict__ print(A.__dict__) print(aa.__dict__)
my_module1.py
__all__ = ['testA'] def testA(a, b): print( a + b) print('testA') def testB(a, b): print( a + b) print('testB') # 测试信息 if __name__ == '__main__': testA(3, 4) # __name__ 是系统变量 # print(__name__) # 在当前py文件中运行时,__name__ = __main__;当其他文件调用时 为模块名:my_module1