热点新闻
01.Python基础
2023-07-07 07:55  浏览:583  搜索引擎搜索“养老服务网”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在养老服务网看到的信息,谢谢。
展会发布 展会网站大全 报名观展合作 软文发布

Python爬虫快速实战

目标: 通过四天的学习,具备爬虫(Python)初级工程师的能力,胜任接口(API)自动化测试、数据采集(爬虫)的岗位要求。

第一天:Python基础

Python的编程环境: 3.6/3.7

交互式环境:命令行(cmd)中直接输入python 【回车】后进入交互式环境,此环境中直接执行python指令。

脚本: 通过记事本(文本编缉器)编写python脚本文件,通过python解释器环境(Pycharm工具)来执行脚本,并显示执行的结果。

1.1 数据类型

1.1.1 基本数据类型

int 整型, 如1, 2, 3等 float 浮点(小数)类型, 如1.15, 3.14等 str 字符类型, 如'祁老师真帅', "disen在西安校区等你"。单引号或双引号必段是英文字符。 bytes 字节类型, 如 b'123', b'abc'。字节类型用于文件流、网络流的传输。通过str.encode()函数,将字符串转成字节数据,一般指定encode()函数中的encoding参数,表示字符的编码类型,默认UTF-8(Python3.7)。可以通过bytes.decode(encoding=None)函数,将字节数据转成字符串。 bool 布尔类型, True 真, False假, 可以通过int(bool值)转成整型,False ->0 , True -> 1, 通过bool(obj)将obj对象转换成布尔值。

【注意】None 类似于C的空指针,表示未知。SyntaxError语法错误(异常)。

type(obj)函数主要获取obj对象的类型, 属于Python自省函数的成员,也是创建类对象的类(元类)。

help(obj.func_name) 查看对象的某一函数的帮助文档, 如 help(bytes.decode), help(str.encode), 按Q键退出。

练习:

bool(0) -> False bool('') -> False bool('a') -> True bool(None) -> False

1.1.2 集合类型

由多个基本类型的数据组成的对象的结构,称之为集合类型。

list 列表类型, 如 [1,2, 3], 和c或java语言中列表或数组有区别,列表中的元素可以是任意类型,而数组的类型是固定的。 tuple 元组, 如(1, 2, 3) dict 字典, 如{‘id’: '1001', 'name': 'disen'}

# list元素类型的示例 person = ['1001', 'disen', 20, 190, 99.5, ['编程', '看电影', '约会']] # 索引操作, obj[索引下标], Python的索引下标从0开始(从左开始),负号表示从右开始(-1 开始)。 person[0] person[2] person[-1] 最后一个元素 person[-1][-1] 获取最后一个列表元素中的最后一个元素 person[-2] 倒数第二个元素 # 索引切片操作 obj[起始位置:结束位置:步长], 默认: 起始为0, 结束为最后一个元素, 步长为1, 如果是-1表示,从右到左切片操作。 person[::-1] person[2:] 结果是 [20, 190, 99.5, ['编程', '看电影', '约会']] person[2:4] 结果是 [20, 190] 不包含4索引下标的内容,即[2, 4)区间。 person[2:-1] 结果是 [20, 190, 99.5], 即不包含最后一个元素。 # 元素操作, append(元素)追加元素, remove(元素)删除元素, insert(index, 元素), pop(index) person.insert(0, 1) 向索引下标0位置插入一个 1元素,原来的0下标元素整体向右移动。 person.pop(0) 弹出索引下标0位置的元素 person.remove('disen') 将disen元素从列表中删除 person.append('disen') 将disen的元素内容追加到列表的末尾。 # 修改元素 person[2] += 2 # 支持修改元素

# tuple 在Python中表示一个集合常量,只有声明时才能添加元组中的元素。定义之后的元组的元素不能修改。 person2 = (1, '1001', 'disen', 190, 99.5) # 索引操作同列表的索引操作 person2[0] person2[2:3] 结果 ('disen',) 元组, 只有一个元素时不能写成('disen'),因为它是优先表达式 person2[0] = 2 # 元组中的元素不能被修改, 解释器会抛出 TypeError异常错误。

# dict 字典 类似于json格式(Javascript对象)【重点】 # 键 key, 值 value, dict的结构称之为键值对 person = {'name': '永琪', 'sex': '男', 'height': 190, 'salary': 100.0} # 修改字典中的key的值 obj[key] = value person['name'] = '凌永琪' person["height"] = 200 # 单位: cm # 获取key的值, obj[key], obj.get(key, default_value) person["salary"] # person['salary'] person.get('salary') 返回value # .get()获取key,如果不存在key,则返回None,当然指定返回的default_value默认值 # [key] 获取key时,如果不存在key, 则解释器抛出异常(KeyError),程序中断执行(发生错误之后) person['salaries'] person.get('salaries') person.get('salaries', 90) # dict对象常用的方法 .values() 返回所有value的列表 .keys() 返回所有key的列表 .items() 返回(key, value)组成的元组结构的列表 .setdefault(key, default_value) 设置key的默认值,如果key存在,则无效, 反之key不存在时,有效。 .pop(key) 弹出key, 实际上从dict中删除key .update(dict) 通过给定的dict参数更新原有的字典。可以达到两个字典合并的效果。 .clear() 清空字典中所有item项目(key, value) .copy() 复制字典,备份字典

【扩展】将dict字典对象转成json格式的字符串(json object {}, json array []) json模块, 导入模块 `import 模块名` json.dumps(dict) 转化为json格式的字符串 json.loads(json_str) 将json格式的字符串转成dict或list对象

【扩展】dir(obj) 查看obj对象中所有属性和方法, 结合help(obj.属性或方法)查看用法说明。

练习:

1. 创建水果的字典, 水果信息包含水果的编号 、类型或品种、价格、产地、规格(单件或整箱) >>> fruits={'编号':1,'类型':'苹果','价格':10,'产地':'西安','规格':'单件'} 2. 查看水果的产地, 并修改为'西安'或`延安` >>> fruits['产地'] '西安' >>> fruits['产地']='延安' >>> fruits['产地'] '延安' 3. 备份水果的字典, 修改原水果的价格和规格 >>> new_fruits = fruits.copy() >>> fruits['价格']=20 >>> fruits['规格']='整箱' >>> fruits {'编号': 1, '类型': '苹果', '价格': 20, '产地': '延安', '规格': '整箱'}

1.1.3 类型转换

字符类型 转换 其它类型

'123' -> 123 int('123', base=10) base表示进制(2进制, 8进制、10进制、16进制) '1000' -> 8 int('1000', base=2) '0b1210' ->725520 int('0b1210', base=16) '1.75' -> 1.75 float('1.75') 'True' -> True bool('True' ) '您好' -> bytes '您好'.encode('utf-8')

其它类型转成字符串类型

str(obj) 将obj对象数据转成str类型, 如果obj是dict类型,转成str之后,可以通过eval()将字符串的字典对象提取出来,执行的结果赋值给指定标识符。

【扩展】eval()函数,把给定的字符串的内容作为Python有效的表达式执行。

eval("a=10+100") # 报错,表达式中不能出现赋值语句。 a = eval("10+100") # 等同于 a = 10+100

dict()函数和list()函数

list()将可迭代(Iteration)对象转成列表, 集合类型和str都是可迭代的。 dict(key=value, key2=value2) 将指定的参数和参数值转成字典

【注】dict也是可迭代的,默认迭代是keys。

>>> person2 {'name': '凌永琪', 'height': 160, 'salary': 100.0, 'weight': 50, 'sex': '女', 'lovies': ['看书', '跑步']} >>> list(person2) ['name', 'height', 'salary', 'weight', 'sex', 'lovies'] >>> list(person2.keys()) ['name', 'height', 'salary', 'weight', 'sex', 'lovies'] >>> list(person.values()) ['凌永琪', 160, 100.0, 50, '女', ['看书', '跑步']] >>> apple = dict(name='青苹果', price=9.5) >>> apple {'name': '青苹果', 'price': 9.5}

1.2 标识符与运算符

标识符(identifier)是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义。在计算机编程语言中,标识符是用户编程时使用的名字,用于给变量、常量、函数、类等命名,以建立起名称与使用之间的关系。

1.2.1 标识符的命名规则

标识符通常由字母和数字以及其它字符构成,在Python中变量名、脚本名、包名、函数名建议使用小写字符,遇到词组,则以下划线_相连,类名使用驼峰命名(首字母大写),如 SystemManager, ClientThread, ServerThread。

标识符的命名不能使用Python中的关键字,通过help('keywords')查看python中的关键字。

1.2.2 Python支持的运算符

算术运算符

+ 加法、 - 减法、 * 乘法、 ** 次幂、 / 除法取整和小数、 // 除法取整、 % 取余数 += , -= , *=, **=, /=, //=, %=

a = (23+102-5*20)/15 LaTex数学语法

a=round( (2**3+10**2-5*20)/15, 2) # round()四舍五入的函数 >>> a = (2**3 + 10**2 -5*20)/15 >>> a 0.5333333333333333 >>> a = round((2**3 + 10**2 -5*20)/15,2) >>> a 0.53

关系运算符**

> 大于 >= 大于等于 < 小于 <= 小于等于 == 内容相等 != 内容不相等 is 内容和内存地址都相等【了解】 is not 内容和内存地址都不相等

逻辑运算符

and 且的关系,and 两边的bool值都为True是,则结果True or 或的关系,两边有一个存在True,则结果为True not 取反, 对False取反则为True, 对True取反则为False

位运算符

将数值转成二进制数据,从低位向高位进行计算。

bin(数值) 将10进制的数值转成二制的字符串,如下所示:

b1, b2 = bin(9), bin(10)

1001 9 1010 10 ^ = 0011 3 ----------------------- 1001 9 1010 10 | =1011 11 ----------------------- 1001 9 1010 10 & =1000 8

| 位或, 同一位的两个数中任一个是1,则为1,反之为0 & 位与, 同一位的两个数都是1,则为1,反之为0 ^ 位异或, 同一位的两个数不相同时为1,反之为0 |= &= ^=

优先级

算术运算 优先于 位运算和关系运算 位运算 优先于 关系运算 关系运算 优先于 逻辑运算 小括号 ( ) 最优先

4+5 | 10 > 5 or 10//2 > 3

【注意】Python不支持自增++或自减--运算符。

1.3 分支与循环

1.3.1 if分支语句

if 逻辑表达式: 表达式结果为True的语句块 else: 表达式结果为False的语句块

n1 = int(input('输入一个数字:')) if n1 > 10: print('输入的数字大于10') # 行前向右缩进了2个空格 else: print('输入的数字小于10') # 同一层的缩进空格的数量保持一致

if 逻辑表达式: 表达式结果为True的语句块 elif 逻辑表达式2: 表达式2结果为True的语句块 elif 逻辑表达式3: 表达式3结果为True的语句块 else: 最近表达式结果为False的语句块

import random # 随机模块 # n1 = float(input('输入本次考试的成绩:')) n1 = random.randint(0, 100) if n1 > 90: print('A') elif n1 > 80: print('B') elif n1 > 70: print('C') elif n1 > 60: print('D') else: print('你的成绩太差了, 重学一年')

1.3.2 if分支表达式

在Python中的三元表达式使用 if 和else分支表达式,如下所示:

select_opt = int(input('输入你的选择: 0 退出, 1 重新开始')) cmd = 'exit' if select_opt == 0 else 'restart'

类似于java中的三目运算符条件?为true值:为假的值

1.3.3 while循环

while 逻辑表达式: 循环执行语句 [改变条件表达式中变量值] [如果逻辑表达式直接为True,则存在退出循环的条件判断] [continue | break]

s,i = 0, 1 while i <= 10: s += i # 计算10以内数值和 i += 1 print(s) # 55

# 练习: 计算100以内除了3的陪数以外的所有数的和

s, i = 0, 1 for i in range(100): if i % 3 == 0: continue else: s += i print(s)

i,sum=1,0 while i<=100: if(i%3!=0): sum+=i i+=1 print(sum)

1.3.4 for循环

for 变量名 in 可迭代对象: 循环执行的语句

for 循环一般用于迭代list、tuple这种可迭代对象的。也可以通过range()函数生成迭代器。

person = {'name': '凌永琪', 'height': 160, 'salary': 100.0, 'weight': 50, 'sex': '女', 'lovies': ['看书', '跑步']} # 从person中每一次迭代获取的元素或内容赋值给 k 变量。k变量名可任意的有效字符。 for k in person: # 字典对象迭代是它的所有的key value = person.get(k) # 判断value是否为int类型的数值 # isinstance 和 type、 dir 三个函数都属于自省函数 if isinstance(value, int): print('找到了value为int类型的内容', k, value)

【推导式】

列表的推导式: [ 变量名 for 变量名 in range(0, 10) 或 可迭代的对象 [条件表达式] ] 生成器的推导式:( 变量名 for 变量名 in range(0, 10) 或 可迭代的对象 [条件表达式] ) ,生成器是可迭代的对象。generator类型名, 它的结构类似于栈, 只能被迭代一次。

# 练习: 从ns列中提取出5的倍数的数值 ns = [9, 10, 20, 45] [ n for n in ns if n % 5 == 0]

# 练习: 随机产生100个学生的Python课程的成绩, 成绩的范围是[0, 100] import random python_scores = [ random.randint(0, 100) for i in range(100) ] print(python_scores) # len(list|dict|tuple|str) 获取指定类型对象的长度, 用于list或str或tuple print(len(python_scores))

【练习】元素位置互换问题: 将”08,45,68,56,44”想变成”80,54,86,65,44”

>>> [item.strip()[::-1] for item in a.split(',')] ['80', '54', '86', '65', '44'] >>> ','.join([item.strip()[::-1] for item in a.split(',')]) '80,54,86,65,44'

【提示】选择str.split(',') 以逗号分隔元素生成一个list列表,再通过推导式和str的索引切片操作,将内容互换,再通过','.join(可迭代对象)将列表中的互换位置之后的元素以逗号的方式拼接成一个字符串。

参考以下的代码:

>>> s = '2, 22, 78, 61, 21' >>> s.split(',') ['2', ' 22', ' 78', ' 61', ' 21'] >>> [ item.strip()[::-1] for item in s.split(',') ] ['2', '22', '87', '16', '12'] >>> ','.join([ item.strip()[::-1] for item in s.split(',') ]) '2,22,87,16,12' >>>

str.strip()函数是删除字符串的两端的空白,类似于java中String对象的trim()函数。

>>> g1 = (i for i in range(0, 10)) >>> g1 <generator object <genexpr> at 0x7fd3034b2a98> >>> list(g1) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list(g1) []

【作业】获取str对象的方法,自我尝试使用str对象的相关方法(5到10个方法)。

# dir('abc') # help(str.strip)

>>> dir(str) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] >>> 'hellodisen'.capitalize() 'Hellodisen' >>> 'hellodisen'.title() 'Hellodisen' >>> 'redapple'.title() 'Redapple' >>> 'red,apple'.title() 'Red,Apple' >>> 'red,apple'.capitalize() 'Red,apple' >>> 'abc.txt'.endswith('.txt') True >>> files = ['a.txt', 'b.png', 'c.txt'] >>> [filename for filename in files if filename.endswith('.txt')] ['a.txt', 'c.txt'] >>> 'a.txt'.replace('a', 'day02') 'day02.txt' >>> 'hi,disen'.find('i') 1 >>> 'hi,disen'.rfind('i') 4 >>> 'hi,disen'.find('c') -1 >>> 'hi,disen'.index('i') 1 >>> 'hi,disen'.rindex('i') 4 >>> 'hi,disen'.index('c') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: substring not found >>>

1.4 函数定义与装饰器

函数作用: 封装复杂的功能代码,提高代码的重复使用率。

1.4.1 函数的定义

def 函数名([参数列表]): 函数功能 [return 函数结果]

# 定义计算某个数值内的和 def sum_n(n): s, i = 0, 1 while i <= n: s += i i += 1 return s

# 列出指定目录下的文件, 需要使用os模块 import os def ls_files(dir_path): files = os.listdir(dir_path) # 返回一个文件列表 for filename in files: # os.path.join(dir, filename) 将文件名和目录拼接成文件的完整路径 print( os.path.join(dir_path, filename) ) # 没有return 语句,则默认返回None

>>> os.listdir('./sql') ['w18.sql', '4.sql', '5.sql', '2.sql', '3.sql', '1.sql', 'w8.sql'] >>> os.getcwd() '/Users/apple'

>>> ls_files('./sql') ./sql/w18.sql ./sql/4.sql ./sql/5.sql ./sql/2.sql ./sql/3.sql ./sql/1.sql ./sql/w8.sql

./sql 指当前目录下的sql子目录(相对路径)。如果Window指定绝对路径r'd:\sql'

1.4.2 函数的参数

形参: 定义函数时声明的参数

实参: 调用函数时,传递的参数(值, 引用)

  • 值传参:标识符(变量)指向的内容在常量池(内存区), 如 a=100, sum_n(a)

  • 引用传参:标识符指向的内容在堆内存中, 如 l=[1, 2, 3], sum_list(l)

在调用函数时,可以按参数的位置从左到右依次传参(位置传值), 还可以指定参数名传参(关键参数传值)。

def sum_ns(n1, n2, n3, n4): print(n1, n2, n3, n4) return n1+n2+n3+n4

sum_ns(1, 2, 3, 4) # 位置传值 sum_ns(4, n4=1, n2=10, n3=90) # 关键参数传值,从使用关键参数方式传值的位置开始,后面所有的参数必须是关键参数的方式。

在声明或定义函数时,可以指定形参的默认值

def sum_ns(n1, n2, n3=10, n4=100): print(n1, n2, n3, n4) return n1+n2+n3+n4

sum_ns(1, 2) # 传参时,带有默认值的参数,可以不用传值。 sum_ns(1,2, 1000, 10000) # 带有默认值的参数,也可以传值

声明形参时,可以使用不定长参数

  • 位置参数 *args, args是元组类型
  • 关键参数 **kwargs , kwargs是字典类型

def sum_ns(*args): print(args) return sum(args) # python内置求和函数 sum

sum_ns(1,2) # 可以只传2个 sum_ns(1,2,3) # 可以只传3个, 也可以传更多的参数

# 通过字典对象的数据生成insert 插入的SQL语句 def save(table_name, **data): # insert into 表名(列名1, 列名2,...) values(列值1, 列值2, ...) # str字符串的格式化(%、format) sql = 'insert into %s(%s) values(%s)' fields = ','.join(data.keys()) values = [] for k in data: v = data[k] # 判断数据类型, 如果字符类型(varchar),在mysql数据库中,加''单引号 if isinstance(v, int) or isinstance(v, float): values.append("%s" % v) # "1" else: values.append("'%s'" % v) # "'disen'" values = ','.join(values) full_sql = sql % (table_name, fields, values) print(full_sql) # pass # pass 表示省略代码(保留),保持函数结构的完整性

>>> '%s' % 'disen' 'disen' >>> 'hi, %s' % 'jack' 'hi, jack' >>> 'hi, %s, city at %s' % ('disen', '西安') 'hi, disen, city at 西安' >>> 'hi, %(name)s,city at %(city)s' % {'name': 'jack', 'city': '西安'} 'hi, jack,city at 西安' >>>

save('tb_user', id=1, name='disen', age=20, salary=1000, years=10, height=180, city='西安', address="立人科技") # insert into tb_user(id,name,age,salary,years,height,city,address) # values (1, 'disen',20, 1000,10,180,'西安', '立人科技')

save('tb_store', id=1, name='disen爱心水果店', day_open='08:00', day_close='18:00') # insert into tb_store(id,name,day_open, day_close) # values (1, 'disen爱心水果店', '08:00', '18:00')

1.4.3 函数的生成器

# next在Python中存在一个内置的函数 def _next_(arr): for n in arr: yield n # 将当前的函数转成生成器,产生一个可迭代的元素,好处:节省内存

生成器对象可以被for循环迭代, 也可以通过next(generator)获取生成器产生的元素,如果生成器中的元素不产出了,但强行执行next()函数时,则抛出StopIteration异常错误。

>>> ne = _next_([1,2,3,4]) >>> for n in ne: ... print(n) ... 1 2 3 4 >>> for n in ne: ... print(n) ... >>> ne = _next_([1,2,3,4]) >>> next(ne) 1 >>> next(ne) 2 >>> next(ne) 3 >>> next(ne) 4 >>> next(ne) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>

1.4.4 函数装饰器

装饰器是一种设计模式(23种)思想, 主要解决扩展现有代码(程序)的功能,不会影响现有的功能。

import time

# 声明装饰器函数,如实现被装饰函数的运行时间 def runtime(func): def wrapper(*args, **kwargs): # print('--扩展功能--') start_time = time.time() # 获取当前的时间戳 ret = func(*args, **kwargs) end_time = time.time() print('耗时(秒)', round(end_time - start_time, 4)) return ret return wrapper

# 使用装饰器函数 # 实现n的数值以内的所有数的和,e表示某个数陪数不参与计算 @runtime def sum_n(n=100, e=None): s, i = 0, 1 while i<=n: if e is not None: if i % e != 0: s += i else: s += i i += 1 # 每一次循环,增加一点休眼时间 time.sleep(0.01) return s

在Python中,某一个函数上方使用装饰器函数,则会按照闭包流程产生一个闭包函数,当调用被装饰的函数时,实际上调用是这个闭包函数(产生条件:内部函数持有外部函数的引用)。

1.5 类与对象

类: 由多个具有相同的属性(特征)和方法(行为)的对象抽象出来的类型

对象: 由类实例化出来的具体的事物。

1.5.1 定义类

# 定义学生类 # Python中所有类的父类(基类)都是object类 class Student(object): # 定义类的初始化实例属性的方法 def __init__(self, sn, name, age, sex): # self 当前类的实例对象引用, 类似于java中类方法中this self.sn = sn # 将方法的参数赋值给实例的属性(动态) self.name = name self.age = age self.sex = sex self.cources = [] # 所有类的实例方法,第一个参数self表示当前的实例对象 def select_cource(self, cource_name): self.cources.append(cource_name) # 取消选择课程 def unselect_cource(self, cname): # 判断 cname课程名是否存在于当前已选择的课程中 if cname in self.cources: self.cources.remove(cname) else: print('你取消的课程 %s 不存在于已选择的课程列表中' % cname) def show_info(self): print(self.sn, self.name, self.age, self.sex, self.cources)

1.5.2 类的实例化

s1 = Student('01', '婷婷', 21, '女') # 先创建类的实例,再调用__init__()方法 s1.select_cource('Python') s1.select_cource('Java') s1.select_cource('H5') s1.show_info() # 调用对象方法时,无须考虑形参中的self参数,因为方法由对象调用的,当前对象自动传入到self

1.6 包与模块

包(package 文件目录)和模块(python脚本)属于项目工程的概念,如果一项工程非常庞大,可以借助包或模块拆分或细化软件工程,便于多人协作开发和代码维护。

包: 文件目录+__init__.py , __init__.py文件初始化当前的package包, 在此脚本声明的变量或编写的函数都属于单例模式,即无论包使用(导入)多少次,初始化脚本(__init__.py)只会执行一次。

导包: 导入 import 包名(文件目录名)

模块: 某一个包(package)下的一个python脚本。

zzserver(project) |--db (package) |-- __init__.py |-- user_db.py |-- order_db.py |-- goods_db.py |--service |-- __init__.py |-- user_service.py |--utils |-- __init__.py |--view |-- __init__.py |--pay |-- __init__.py |--order |-- __init__.py

# user_db.py内容 class UserDB: pass class User: pass

# order_db.py内容 class OrderDB: pass

# 在 user_service.py脚本中导入db包下的user_db.py中 UserDB类 from db.user_db import UserDB # 同一个模块的导入场景 from db.user_db import User from db.order_db import OrderDB

1.7 with上下文与异常

在Python中,所有的对象都可以托管给上下文管理器,使用 with关键字,语法如下:

with obj [as 标识符]: # 进入上下文 # 功能 pass # 退出上下文

【注意】obj托管上下文之前,obj所属的类必须 实现__enter____exit__两个方法,如果没有实现,则抛出异常。

上下文管理器作用: 确定程序正常执行,在代码执行之前,分配资源;在执行完成后,可以合理地回收资源。

当对象obj进入上下文时,调用obj.__enter__函数, 当退出上下文时,调用obj.__exit__函数。

class DB: def __enter__(self): print('--进入上下文--') self.conn = '已连接' return self.conn # 可以没有返回 def __exit__(self, except_type, msg, tb): print('--退出上下文--') self.conn = None if except_type: # 存在异常错误 print('存在异常', msg) return True # True表示如果出现的异常,则内部消化; False 表示如果出现异常,则由外部程序处理。

db = DB() with db as c: # as 指定标识符来接收enter函数返回结果或数据 print(c) print(10/0) print('--gogogo---') print(db.conn) # 退出上下文时,db.conn为None

1.8 文件操作

Python中文件读写操作之前,必须先打开文件,使用open()函数。

open(file, mode='r', buffering=-1, encoding=None)

  • file表示文件的路径(相对路径或绝对路径)
  • mode 文件打开模式,如果文件准备写操作,则mode应该写相对应字符,如'w'或'a'、'r+'、'w+'
    • w 只写文本
    • r 只读文本
    • rw 读写文本
    • r+ 读写文本, 如果文件不存在,则抛出异常
    • w+读写文本,如果文件不存在,则会自动创建; 另外,原内容则会被重写。
    • a 追加文件内容,在文件的末尾行新增内容, 原内容还存在。
    • r+b 读写字节数据
    • w+b 读写字节数据
    • ab 追加字节数据
  • buffering 指定读写数据的缓存大小,默认为-1,表示全部写入或全部读取。
  • encoding 表示读取文本数据的字符集,如果是b的字节模式,则不能设置encoding,否则抛出异常。

# 编写python的打印helloworld脚本,脚本名为a.py stream = open('a.py', 'w', encoding='utf-8') # 以只写的模式打开文件,返回一个文件流对象 stream.write("print('hello, world')") stream.close()

stream = open('a.py', 'r', encoding='utf-8') stream.read()

stream = open('a.py', 'w+', encoding='utf-8') stream.write("print('hello, world')") # 写入之后,文件句柄(指针)指向文件末尾的位置 stream.seek(0) # 移动文件句柄到每一个字符的前面 stream.read()

文件流stream可以在with 中使用:

with open('a.py', 'w+', encoding='utf-8') as stream: stream.write("print('hello, world')") # 写入之后,文件句柄(指针)指向文件末尾的位置 stream.seek(0) # 移动文件句柄到每一个字符的前面 stream.read()

发布人:661e****    IP:117.173.23.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发