Python语言系列-03-文件操作和函数
## 深浅拷贝
#!/usr/bin/env python3
# author:Alnk(李成果)
# 赋值运算
# 可变的数据类型:由于数据类型可变,修改数据会在原来的数据的基础上进行修改,
# 可变的数据类型有:列表,字典
l1 = [1, 2, 3]
l2 = l1
l3 = l2
# l1 = [1, 2, 3, 4] # 注意这不是修改数据,而是在内存中重新创建了一份数据,然后L1 指向了这份新数据
l1.append(666) # 在原来的数据上修改
print(l1, l2, l3) # [1, 2, 3, 666] [1, 2, 3, 666] [1, 2, 3, 666]
print(id(l1), id(l2), id(l3)) # 140349669255176 140349669255176 140349669255176
print("--" * 30)
# 不可变的数据类型:由于数据类型是不可变的,不可修改,会在内存中在重新创建一份新的数据
# 不可变的数据类型有:字符串,数字,bool值,元组等
l4 = 'abcd'
l5 = l4
l4 = [1, 2, 3]
print(l4, l5) # [1, 2, 3] abcd
print(id(l4), id(l5)) # 140230928510856 140230926894952
print("--" * 30)
# 浅copy
# copy一个新列表(dict),列表在内存中是新的,但是列表里面的元素,完全沿用之前的元素。
l5 = [1, 2, 3, [22, 33]]
l6 = l5.copy()
print(id(l5), id(l6)) # 140589566668360 140589566718024
l5.append(666)
l5.remove(1)
print(l5, l6) # [2, 3, [22, 33], 666] [1, 2, 3, [22, 33]]
print("--" * 30)
# 列表在内存中是新的,但是列表里面的元素,完全沿用之前的元素
l5 = [1, 2, 3, [22, 33]]
l6 = l5.copy()
print(id(l5[0])) # 4459755568
print(id(l6[0])) # 4459755568
l5[-1].append(666)
print(l5, l6) # [2, 3, [22, 33, 666], 666] [1, 2, 3, [22, 33, 666]]
print("--" * 30)
# 深copy
# 总结 深copy则会在内存中开辟新空间,将原列表以及列表里面的可变的数据类型重新创建一份,
# 不可变的数据类型则沿用之前的,指向之前的数据
import copy
l7 = [1, 2, 3, [22, 33]]
l8 = copy.deepcopy(l7)
print(id(l7), id(l8)) # 140686186753032 140686186752968
l7[-1].append(666)
l7.remove(1) # 只是删除了l1列表中和内存中的数据1的指向关系,并不是在内存中删除了数据1
print(l7, l8) # [2, 3, [22, 33, 666]] [1, 2, 3, [22, 33]]
print("--" * 30)
# id 对象的内存地址
# == 比较两边的数值是否相等
# is 判断的两边对象的内存地址是否是同一个
print(2 == 2)
print("--" * 30)
# 切片是浅copy ******
l1 = [1, 2, 3, [22, 33]]
l2 = l1[:] # 切片是浅copy
l1[-1].append(666)
print(id(l1), id(l2)) # 40282048785864 140282048785608
print(l1, l2) # [1, 2, 3, [22, 33, 666]] [1, 2, 3, [22, 33, 666]]
文件操作
文件操作介绍
#!/usr/bin/env python3
# author:Alnk(李成果)
"""
文件三参数
path:文件的路径
encoding:文件以什么编码方式存储,就以什么编码方式读取
mode:读,写,读写,写读,追加,改等等
三个大方向:
带b的模式操作对象都是非文字类的文件:视频,音频,图片。
读(r rb r+ rb+)
r 读模式
rb
r+ 读写模式
rb+
写 w wb w+ w+b :如果原文件存在,则清空原文件,在写入。这个慎用
w 写模式
wb
w+ 写读模式
wb+
追加(a ab a+ a+b)
a 追加
ab
a+
ab+
文件操作的其他方法:
f.read()
f.write()
f.readline()
f.readlines()
f.close()
f.seek()
f.tell()
"""
f1 = open("test.txt",encoding='utf-8',mode='r')
content = f1.read()
print(content)
f1.close()
"""
f1变量,文件句柄。
open 内置函数,底层调用的操作系统的操作文件功能的接口。
windows: gbk,linux:utf-8 ios: utf-8
操作文件总共3步;
1,打开文件,产生文件句柄。
2,对文件句柄进行操作。
3,关闭文件句柄。
"""
"""
# 错误示范:
# 1,UnicodeDecodeError: 'gbk' codec can't decode... 编解码错误。
# 2,路径错误。路径分隔符 与后面的字符产生特殊的意义。 解决方式 r 或者 \
#f1 = open(r"d:\test\r文件读写test.txt",encoding='utf-8',mode='r')
"""
文件操作-读模式
#!/usr/bin/env python3
# author:Alnk(李成果)
# 读模式(r rb r+ rb+)
# r模式
# 默认就是r模式
# 1.1 read() # 全部读取文件内容,如果文件过大,可能会导致内存不足
f1 = open('test.txt', encoding='utf-8', mode='r')
content = f1.read()
print(content, type(content)) # <class 'str'> 对文件进行读取出来的都是字符串类型
print("=" * 30)
# 1.2 read(n)
# r模式下, n代表字符。
f1 = open('test.txt', encoding='utf-8', mode='r')
content = f1.read(3)
print(content)
print("=" * 30)
# 1.3 readline() 按行读取
f1 = open('test.txt', encoding='utf-8', mode='r')
print(f1.readline().strip())
print(f1.readline().strip())
print(f1.readline().strip())
f1.close()
print("=" * 30)
# 1.4 readlines() 返回一个列表,列表里面的元素是原文件每一行
f1 = open('test.txt', encoding='utf-8', mode='r')
content = f1.readlines()
print(content)
f1.close()
print("=" * 30)
# 1.5 for循环 *****注意平常读取大文件就需要用这种方法
f1 = open('test.txt', encoding='utf-8', mode='r')
for line in f1:
print(line.strip())
f1.close()
print("=" * 30)
# rb模式 读取一些非文字类的文件,如图片,视频等
# 5种读的模式, read() read(n) readline() readlines() for循环读取
# 如果是 rb 模式,就不需要规定编码了 encoding不是编码或解码,它是规定你这个文件到底采用哪种编码模式而已
f1 = open('test.txt', mode='rb')
content = f1.read()
print(content)
print(content.decode('utf-8')) # 解码 utf-8 ---> unicode
f1.close()
print("---rb---")
print("=" * 30)
# rb 模式读取图片
f1 = open('time1.jpg', mode='rb')
content = f1.read()
print(content)
f1.close()
print("=" * 30)
# r+ 读写模式
f = open('log1', encoding='utf-8', mode='r+')
print(f.read())
f.write('666\n')
f.close()
print("=" * 30)
# 先写后读会出问题 会覆盖
f = open('log1', encoding='utf-8', mode='r+')
f.write('松岛岛')
print(f.read())
f.close()
print("=" * 30)
# rb+ 模式
文件操作-写模式
#!/usr/bin/env python3
# author:Alnk(李成果)
# w 写模式
# 没有文件,创建文件写入内容
# 有文件,先清空内容后写入
f = open('log1', encoding='utf-8', mode='w')
f.write('123456')
f.write('深圳 ~~~')
f.write('深圳 ~~~')
f.write('深圳 ~~~')
f.write('深圳 ~~~')
f.write('深圳 ~~~')
f.close()
# wb 写模式(以bytes类型写入到文件)
# 把bytes类型写入到文件 --图片
f1 = open('time1.jpg', mode='rb')
content = f1.read()
f1.close()
f2 = open('time2.jpg', mode='wb')
f2.write(content)
f2.close()
# w+ 写读模式
f = open('log1', encoding='utf-8', mode='w+')
f.write('老男孩教育...')
f.seek(0) # 调整光标(指针)到最开始
print(f.read())
f.close()
# wb+ 写读模式(bytes)
文件操作-追加模式
#!/usr/bin/env python3
# author:Alnk(李成果)
# a 追加
# 没有文件创建文件追加内容,有文件,在文件最后追加内容。
f = open('log3', encoding='utf-8', mode='a')
f.write('老男孩')
f.close()
# 有文件,在文件最后追加内容。
f = open('log1', encoding='utf-8', mode='a')
f.write('666')
f.close()
文件操作-修改
#!/usr/bin/env python3
# author:Alnk(李成果)
# 文件的修改:所有的文件编辑器都要经过下面这5步才能对文件进行修改
# 1,以读的模式打开原文件
# 2,以写的模式打开新文件
# 3,读取原文件对源文件内容进行修改形成新内容写入新文件
# 4,将原文件删除
# 5,将新文件重命名成原文件
# # 方法一 小文件可以
# # 1,以读的模式打开原文件
# # 2,以写的模式打开新文件
# import os
# with open('tom个人简历', encoding='utf-8') as f1, open('tom个人简历.bak', encoding='utf-8', mode='w') as f2:
# # 3,读取原文件对源文件内容进行修改形成新内容写入新文件
# old_content = f1.read()
# new_content = old_content.replace('tom', 'SB')
# f2.write(new_content)
# # 4,将原文件删除。
# os.remove('tom个人简历')
# # 5,将新文件重命名成原文件。
# os.rename('tom个人简历.bak', 'tom个人简历')
# 方法二: 推荐使用这种方法
# 1,以读的模式打开原文件。
# 2,以写的模式打开新文件。
import os
with open('tom个人简历', encoding='utf-8') as f1, open('tom个人简历.bak', encoding='utf-8', mode='w') as f2:
# 3,读取原文件对源文件内容进行修改形成新内容写入新文件。
for old_line in f1:
new_line = old_line.replace('SB', 'tom')
f2.write(new_line)
# 4,将原文件删除。
os.remove('tom个人简历')
# 5,将新文件重命名成原文件。
os.rename('tom个人简历.bak', 'tom个人简历')
文件操作-其他常用方法
#!/usr/bin/env python3
# author:Alnk(李成果)
# 其他操作方法:
# readable() writable() *** 文件句柄是否可读,可写
# seek 调整光标位置 按照字节 ***
# seek(0) 将光标移动到开始
# seek(0,2) 将光标移动到最后。
# tell 获取光标位置 按照字节。 ***
# flush 刷新 保存 ***
# truncate 截取原文件,从头开始截,
f = open('log3', encoding='utf-8')
f.seek(1)
print(f.read())
print(f.tell())
f.seek(0) # 将光标移动到开始
print(f.read())
f.seek(0, 2) # 将光标移动到最后
print(f.read())
f.close()
print("---" * 30)
# writable() 是否可写
f = open('log3', encoding='utf-8')
print(f.read())
print(f.writable()) # False 是否可写
if f.writable():
f.write('111')
f.close()
print("---" * 30)
# flush()
f = open('log3', encoding='utf-8', mode='w')
f.write('fjdsklafjdfjksaadfadf')
f.flush()
f.close()
# 截取原文件,从头开始截,需要在可写的模式下,并且不清空原文件
f = open('log3', encoding='utf-8', mode='r+')
f.truncate(3)
f.close()
函数
函数的初识
#!/usr/bin/env python3
# author:Alnk(李成果)
"""
# 面向过程编程
s1 = 'hello jerry'
count = 0
for i in s1:
count += 1
print(count)
l1 = [1, 2, 3, 4, 5]
count = 0
for i in l1:
count += 1
print(count)
# 缺点:
# 1,代码重复太多。
# 2,代码的可读性差。
"""
# 函数的初识
def my_lf_len(s):
sun = 0
for _ in s:
sun += 1
print(sun)
s1 = 'hello word'
my_lf_len(s1)
l1 = [1, 2, 3, 3, 5, 56, 6, 6]
my_lf_len(l1)
# 1,函数是什么?
# 功能体,一个函数封装的一个功能
# 结构:
'''
def 函数名():
函数体
'''
# 2,函数什么时候执行
# 被调用的时候执行 函数名+()
def my_lf_len(s):
sum = 0
for _ in s:
sum += 1
print(sum)
my_lf_len('how are you?')
# 3,函数的返回值 return
def tantan():
print('搜索')
print('左滑动一下')
print('右滑动一下')
# return
print('发现美女,打招呼')
# return '美女一枚'
# return ['恐龙一堆']
# return '小萝莉', '肯德基', '御姐'
return {'name': 'alnk', 'age': 18}, [1, 2, 3, 4, 5] # 这算多个值
ret = tantan()
print(ret, type(ret))
# 调用一次执行一次
tantan()
tantan()
tantan()
# 返回值
'''
return:
1,终止函数
2,给函数的调用者(执行者)返回值
return ---> None
return 单个值 ---> 单个值 --被返回的数据是什么数据类型就是什么类型
return 多个值 ---> (多个值,) --元组
'''
函数的参数
#!/usr/bin/env python3
# author:Alnk(李成果)
# 实参和形参
def Tantan(sex): # 函数的定义:sex形式参数,形参
print('搜索')
print('左滑动一下')
print('右滑动一下')
print('发现美女,打招呼')
return '小萝莉', '肯德基', '御姐'
# 函数的参数
Tantan('女') # 函数的执行:'女' 实际的数据, 实参
# 从两方面讲函数的参数:实参 和 形参
# 一 实参角度
# 1.位置参数 从左至右,一一对应
def Tantan(sex, age):
print('筛选性别%s,年龄%s左右' % (sex, age))
print('搜索')
print('左滑动一下')
print('右滑动一下')
print('发现美女,打招呼')
Tantan('女', 28)
print("----" * 30)
# 练习:比大小,返回大的数字
def max_(a, b):
# if a > b:
# return a
# else:
# return b
# return a if a > b else b
return a if a > b else b
print(max_(100, 200))
print("----" * 30)
# 扩展:三元运算符
a = '饼'
b = '西瓜'
ret = a if 3 > 2 else b
print(ret)
print("----" * 30)
# 2.关键字参数 一一对应。
# 函数参数较多 记形参顺序较麻烦时,需要关键字参数
def Tantan(sex,age,area):
print('筛选性别%s, %s附近,年龄%s左右的美女' %(sex,area,age))
print('搜索')
print('左滑动一下')
print('右滑动一下')
print('发现美女,打招呼')
Tantan(sex='女',area='南山区',age='28')
print("----" * 30)
# 3.混合参数 一一对应,关键字参数必须要在位置参数后面。
def Tantan(sex,age,area):
print('筛选性别%s,%s 附近,年龄%s左右的美女' %(sex,area,age))
print('搜索')
print('左滑动一下')
print('右滑动一下')
print('发现美女,打招呼')
Tantan('女',28,area='南山区')
print("----" * 30)
# 二 形参角度
# 1.位置参数 从左至右,一一对应。
def Tantan(sex,age):
print('筛选性别%s,年龄%s左右' %(sex,age))
print('搜索')
print('左滑动一下')
print('右滑动一下')
print('发现美女,打招呼')
Tantan('女', 28)
print("----" * 30)
# 2.默认参数 : 使用最多的一般不更改的参数,默认参数一定放在位置参数后面
def Tantan(area,age,sex='girl'):
print('筛选性别%s, %s 附近,年龄%s左右的美女' %(sex,area,age))
print('搜索')
print('左滑动一下')
print('右滑动一下')
print('发现美女,打招呼')
Tantan('南山区',28,'laddboy')
print("----" * 30)
# 3.万能参数(动态参数) *args, **kwargs
def Tantan(*args, **kwargs):
# 函数的定义: * 代表聚合。
# * 将实参角度所有的位置参数放到一个元祖中,并将元组给了args
# ** 将实参角度所有的关键字参数放到一个字典中,并将字典给了kwargs
print(args)
print(kwargs)
# print('筛选地域:%s,年龄%s' % args)
# print('搜索')
# print('左滑动一下')
# print('右滑动一下')
# print('发现美女,打招呼')
# print(kwargs)
# Tantan('南山区','28', '性格好','身材好', '家境好')
Tantan('南山区', '28', body='身材好', voice='萝莉音', money='白富美')
print("----" * 30)
def Tantan(*args,**kwargs):
# 函数的定义: * 代表聚合。
# * 将实参角度所有的位置参数放到一个元祖中,并将元组给了args
# ** 将实参角度所有的关键字参数放到一个字典中,并将字典给了kwargs
print(args)
print(kwargs)
Tantan('南山区','28',body='身材好',voice='萝莉音',money='白富美')
print("---- 1 -----------------------------------------")
l1 = [1, 2, 3]
l2 = (4, 5, 6)
Tantan(*l1, *l2) # 函数的执行:*iterable 将l1打散,添加到args
print("---- 2 -----------------------------------------")
Tantan(1, 2, 3, 4, 5, 6)
print("---- 3 -----------------------------------------")
dic1 = {'name': "tom"}
dic2 = {'age': 46}
Tantan(**dic1, **dic2) # **dic1 将dic1打散,将所有的键值对添加到kwargs
print("---- 4 -----------------------------------------")
# 函数参数
# 实参
# 位置参数
# 关键字参数
# 混合参数
# 形参
# 位置参数
# 默认参数
# 万能参数
# 形参的最终顺序
# 位置参数 *args 默认参数 **kwargs
def func(a, b, *args, sex='女', **kwargs):
print(a, b, sex, args, kwargs)
func(1, 2, 4, 5, 6, name='tom', age=73)
函数的名称空间和顺序
#!/usr/bin/env python3
# author:Alnk(李成果)
"""
函数里面的变量,在函数外面能直接引用么?
def func1():
m = 1
print(m)
print(m) #这行报的错
报错了:
NameError: name 'm' is not defined
我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间
每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读入内存,
表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。等执行到函数调用的时候,
Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,
而函数中的变量会储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
我们给这个‘存放名字与值的关系’的空间起了一个名字 --- 命名空间。
代码在运行伊始,创建存储“变量名与值的关系”的空间叫做全局命名空间;
在函数的运行中开辟的临时的空间叫做局部命名空间。
"""
# python的空间分三种:
# 全局名称空间
# 局部名称空间
# 内置名称空间 print() len() 内置函数
#
# 举例
# def func():
# name = 'tom'
# func()
# print(name) # 报错
# func()
# python中的作用域分两种:
# 全局作用域:内置名称空间 全局名称空间
# 局部作用域:局部名称空间
# 取值顺序: 就近原则
# 局部变量先到局部寻找,局部没找到才去全局找,全局没找到,去内置找,都没找到,就报错
# 全局变量直接在全局查找,全局没有就去内置空间查找,如果没有,就报错
# 局部名称空间 ———> 全局名称空间 ———> 内置名称空间 (这个顺序不可逆)
input = 'tom'
def func():
input = 'jerry'
print(input)
func()
print(input)
# 加载顺序
# 所有的东西要加载到内存才运行
# 内置名称空间 ---> 全局名称空间 ---> 局部名称空间
函数的嵌套
#!/usr/bin/env python3
# author:Alnk(李成果)
# 函数的嵌套
# 举例1
def func():
print(111)
def func1():
print(222)
func()
def func3():
print(333)
func1()
print(444)
func()
print(555)
## 444 111 555
print("---------------- 1 -------------------------")
#举例2
def func():
print(111)
def func1():
print(222)
func()
def func3():
print(333)
func1()
print(444)
func3()
print(555)
# 444 333 222 111 555
print("---------------- 2 -------------------------")
def wrapper():
print(222)
def inner():
print(111)
print(444)
inner()
print(333)
wrapper()
# 222 444 111 333
内置函数globals、locals
#!/usr/bin/env python3
# author:Alnk(李成果)
# 内置函数globals() locals()
name = 'tom'
age = 46
def func():
sex = '男'
hobby = '女'
print(globals()) # 返回一个字典:全局作用域的所有内容
# {..., 'name': 'tom', 'age': 46, ...} 两边还有其他的内容
print(locals()) # 返回一个字典:当前位置的内容
# {'hobby': '女', 'sex': '男'}
func()
print(globals()) # 返回一个字典:全局作用域的所有内容
# {..., 'name': 'tom', 'age': 46, ...} 两边还有其他的内容
print(locals()) # 返回一个字典:当前位置的内容
# {..., 'name': 'tom', 'age': 46, ...} 两边还有其他的内容
函数名的应用
#!/usr/bin/env python3
# author:Alnk(李成果)
# 函数名的应用
# 1,函数名是一个特殊的变量 函数名() 执行此函数
def func():
print(666)
func()
print("--------------- 1 ------------------")
# 2,函数名可以当做变量进行赋值运算。
def func():
print(666)
f = func
f()
print("--------------- 2 ------------------")
# 3,函数名可以作为容器型数据的元素 ***
def func():
print(666)
def func1():
print(777)
def func2():
print(888)
def func3():
print(999)
l1 = [func, func1, func2, func3]
for i in l1:
i()
dic = {
1: func,
2: func1,
3: func2,
4: func3,
}
# while 1:
# num = input('请输入序号:').strip()
# num = int(num)
# dic[num]()
print("--------------- 3 ------------------")
# 4,函数名可以作为函数的参数。
def func1():
print(111)
def func2(x):
x()
print(222)
func2(func1)
print("--------------- 4 ------------------")
# 5,函数名可以作为函数的返回值。
def func1():
print(111)
def func2(x):
print(222)
return x
ret = func2(func1)
ret()
关键字global、nonlocal
#!/usr/bin/env python3
# author:Alnk(李成果)
# global nonlocal
# global
# 1,声明一个全局变量。
def func():
global name
name = 'tom'
func()
print(name)
print("--------------- 1 ------------------")
# 2,修改一个全局变量。
# 原因:局部作用域只能引用全局变量而不能改变全局变量。如果改变则报错
# global 可以实现通过局部作用域而去改变全局变量
count = 1
def func1():
global count
count += 1
print(count)
func1()
print(count)
print("--------------- 2 ------------------")
# nonlocal: 子级函数可以通过nonlocal修改父级(更高级非全局变量)函数的变量。
# 现象:子级函数可以引用父级函数的变量但是不能修改。
def func():
count = 1
def func1():
def inner():
nonlocal count
count += 1
print(count) # 第二个打印 2
print(count) # 第一个打印 1
inner()
print(count) # 第三个打印 2
func1()
func() # 1 2 2
print("--------------- 3 ------------------")
# 这个不行,会报错
# count = 1
# def func1():
# def inner():
# nonlocal count # 这里会报错,因为count是全局变量了,不能使用nonlocal
# count += 1
# print(count)
# inner()
#
# func1()
练习题1
#!/usr/bin/env python3
# author:Alnk(李成果)
"""
# 1、 文件a1.txt内容
# 序号 部门 人数 平均年龄 备注
# 1 python 30 26 单身狗
# 2 Linux 26 30 没对象
# 3 运营部 20 24 女生多
# 通过代码,将其构建成这种数据类型:
# [{'序号':'1','部门':Python,'人数':30,'平均年龄':26,'备注':'单身狗'},......]
"""
# 方法1
l1 = []
with open('a1.txt', encoding='utf-8', mode='r') as f:
k1, k2, k3, k4, k5 = f.readline().strip('').split()
for line in f:
dic = {}
v1, v2, v3, v4, v5 = line.strip('').split()
dic[k1] = v1
dic[k2] = v2
dic[k3] = v3
dic[k4] = v4
dic[k5] = v5
l1.append(dic)
print(l1)
print("----------------------- 1 --------------------------------")
# 方法2
l1 = []
with open('a1.txt', encoding='utf-8', mode='r') as f:
# 读取第一行作为键
head_list = f.readline().strip('').split()
# print(head_list)
for line in f:
# 获取每一行为一个列表
line_list = line.strip().split()
# print(line_list)
dic = {}
# 循环上面的列表 enumerate函数的用法 会返回索引k和值v
for k, v in enumerate(line_list):
# print(k, v)
dic[head_list[k]] = v
l1.append(dic)
print(l1)
print("----------------------- 2 --------------------------------")
# 2、 传入函数的字符串中,统计[数字]、[字母]、[空格] 以及 [其他]的个数,并返回结果。
def my_count(str1):
"""
统计数字,字母,空格,其他的字符个数
:param str1: 字符串
:return: 数字,字母,空格,其他
"""
count_num = 0
count_letter = 0
count_space = 0
count_other = 0
for i in str1:
if i.isdigit():
count_num += 1
elif i.isalpha():
count_letter += 1
elif i == ' ':
count_space += 1
else:
count_other += 1
return '数字[%s] 字母[%s] 空格[%s] 其他[%s]' % (count_num, count_letter, count_space, count_other)
print(my_count('1 b # 3s'))
print("----------------------- 3 --------------------------------")
# 3、 写函数,接收两个数字参数,返回比较大的那个数字
def my_compare(*args):
"""
比较两个数大小
:param args:传入2个数字
:return: 大的数字
"""
return args[0] if args[0] > args [1] else args[1]
print(my_compare(3,62))
print("----------------------- 4 --------------------------------")
# 4、 写函数,检查传入字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者
# dic = {"k1": "v1v1", "k2": [11,22,33,44]} PS:字典中的value只能是字符串或列表
def func(**kwargs):
"""
检查字典值的长度,大于2,保留前两个长度的内容
:param kwargs: 字典
:return: 新列表
"""
for k,v in kwargs.items():
kwargs[k] = v[:2] if len(v) > 2 else v
return kwargs
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
ret = func(**dic)
print(ret)
print("----------------------- 5 --------------------------------")
# 5、写函数,此函数只接收一个参数且此参数必须是列表数据类型,
# 此函数完成的功能是返回给调用者一个字典,此字典的键值对为此列表的索引及对应的元素。例如传入的列表为:[11,22,33]
# 返回的字典为{0:11,1:22,2:33}
def fun(lis):
"""
接受列表数据类型,返回字典
:param args: 列表
:return: 字典
"""
if type(lis) is list:
dic = {}
for k in range(len(lis)):
dic[k] = lis[k]
return dic
else:
return '参数必须为列表'
l1 = [11,22,33,]
print(fun(l1))
print("----------------------- 6 --------------------------------")
# 6、写函数,函数接收四个参数分别是:姓名,性别,年龄,学历。用户通过输入这四个内容,然后将这
# 四个内容传入到函数中,此函数接收到这四个内容,将内容追加到一个student_msg文件中
def func(name,sex,age,edu):
"""
接收四个参数,将接收的内容追加到student_msg文件中
:param name: 姓名
:param sex: 性别
:param age: 年龄
:param edu: 学历
:return:
"""
with open('student_msg', encoding='utf-8', mode='a+') as f:
f.write('%s %s %s %s \n' % (name, sex, age, edu) )
f.flush()
# name = input('name>>>:')
# sex = input('sex>>>:')
# age = input('age>>>:')
# edu = input('edu>>>:')
# func(name,sex,age,edu)
print("----------------------- 7 --------------------------------")
# 7、 对第6题升级:支持用户持续输入,Q或者q退出,性别默认为男,如果遇到女学生,则把性别输入女
def func(name,age,edu,sex='男'):
"""
接收四个参数,将接收的内容追加到student_msg文件中
:param name: 姓名
:param sex: 性别
:param age: 年龄
:param edu: 学历
:return:
"""
with open('student_msg', encoding='utf-8', mode='a+') as f:
f.write('%s %s %s %s \n' % (name, sex, age, edu) )
f.flush()
# while 1:
# name = input('name(Q/q exit)>>>:')
# if name.strip().lower() == 'q':
# break
# sex = input('sex>>>:')
# age = input('age>>>:')
# edu = input('edu>>>:')
#
# if sex.strip() == '男':
# func(name,age,edu)
# else:
# func(name,age,edu,sex)
print("----------------------- 8 --------------------------------")
# 8、写函数,用户传入修改的文件名,与要修改的内容,执行函数,完成整个文件的批量修改操作
import os
def modify_file(file_name,old_modify,new_modify):
"""
文本修改
:param file_name: 文件
:param old_modify: 被修改的内容
:param new_modify: 修改的内容
:return: True
"""
if os.path.exists(file_name):
with open(file_name, encoding='utf-8', mode='r') as f1, open(file_name+'.bak', encoding='utf-8',mode='w') as f2:
for old_line in f1:
new_line = old_line.replace(old_modify,new_modify)
f2.write(new_line)
f2.flush()
os.remove(file_name)
os.rename(file_name+'.bak',file_name)
return True
else:
return '文件不存在'
# file_name = input("请输入文件名称:")
# old_modify = input("请输入需要修改的内容:")
# new_modify = input("请输入修改后的内容:")
# ret = modify_file(file_name,old_modify,new_modify)
# print(ret)
print("----------------------- 9 --------------------------------")
# 9、读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
a = 10
b = 20
def test5(a, b): # a=20 b=10
a=3
b=5
print(a, b) #a=3 b=5
c = test5(b, a) # a=3 b=5 因为在函数内部打印的,先从局部变量开始找
print(c) #none 函数没有return,所以没有返回值C=None。
print("----------------------- 10 --------------------------------")
# 10、写函数,传入函数中多个实参(均为可迭代对象如字符串,列表,元祖,集合等),将每个实参的每个元素依次
# 添加到函数的动态参数args里面
# 例如 传入函数两个参数[1,2,3] (22,33)最终args为(1,2,3,22,33)
def func(*args):
"""
:param args:
:return:
"""
print(args)
l1 = [1, 2, 3]
t1 = (22, 33)
func(*l1, *t1)
print("----------------------- 11 --------------------------------")
# 11、写函数,传入函数中多个实参(实参均为字典),将每个实参的键值对依次添加到函数的动态参数kwargs里面
# 例如 传入函数两个参数{‘name’:’alex’} {‘age’:1000}最终kwargs为{‘name’:’alex’ ,‘age’:1000}
def fun(**kwargs):
"""
:param kwargs:
:return:
"""
print(kwargs)
dic1 = {'name': 'alex'}
dic2 = {'age': 1000}
fun(**dic1, **dic2)
print("----------------------- 12 --------------------------------")
# 12、下面代码成立么?如果不成立为什么报错?怎么解决?
# 题目一:
a = 2
def wrapper():
print(a)
wrapper() # 2
# 题目二:
# a = 2
# def wrapper():
# a += 1 # 报错
# print(a)
# wrapper()
# 题目三:
def wrapper():
a = 1
def inner():
print(a)
inner()
wrapper() # 1
# 题目四:
# def wrapper():
# a = 1
# def inner():
# a += 1 # 报错
# print(a)
# inner()
# wrapper()
# 题目二修改为如下
a = 2
def wrapper():
global a
a += 1
print(a)
wrapper()
# 题目四修改为如下
def wrapper():
a = 1
def inner():
nonlocal a
a += 1
print(a)
inner()
wrapper()
print("----------------------- 13 --------------------------------")
# 13、写函数,接收两个数字参数,将较小的数字返回
def min_(a,b):
return a if a < b else b
print(min_(13,2))
print("----------------------- 14 --------------------------------")
# 14、写函数,接收一个参数(此参数类型必须是可迭代对象),将可迭代对象的每个元素以’_’相连接,形成新的字符串,并返回
# 例如 传入的可迭代对象为[1,'老男孩','武sir']返回的结果为’1_老男孩_武sir’
def fun(item):
"""
:param item:
:return:
"""
s = ''
for i in item:
s = s + '%s_' % (i)
s = s.rstrip('_')
return s
l1 = [1, '深圳', '南山']
ret = fun(l1)
print(ret)
print("----------------------- 15 --------------------------------")
# 15、写函数,传入n个数,返回字典{‘max’:最大值,’min’:最小值}
# 例如:如:min_max(2,5,7,8,4) 返回:{‘max’:8,’min’:2}(此题用到max(),min()内置函数)
def min_max(*args):
dic = {'max':max(args),'min':min(args)}
return dic
ret = min_max(2,5,7,8,4)
print(ret)
print("----------------------- 16 --------------------------------")
# 16、写函数,传入一个参数n,返回n的阶乘
# 例如:cal(7) 计算7*6*5*4*3*2*1
def fun(n):
s = 1
for i in range(1, n+1):
s = s * i
print(s)
fun(7)
print(7 * 6 * 5 * 4 * 3 * 2 * 1)
print("----------------------- 17 --------------------------------")
# 17、写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组
# 例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]
def poker():
poker_list = []
l1 = ['红心','草花','黑桃','方片']
l2 = ['A',2,3,4,5,6,7,8,9,10,'J','Q','K']
for i in l1:
for k in l2:
poker_list.append((i,k))
return poker_list
print(poker())
print("----------------------- 18 --------------------------------")
# 18、 有如下函数:
# def wrapper():
# def inner():
# print(666)
# wrapper()
# 你可以任意添加代码,用两种或以上的方法,执行inner函数
#方法1
def wrapper():
def inner():
print(666)
inner()
wrapper()
#方法2
def wrapper():
def inner():
print(666)
return inner
ret = wrapper()
ret()
练习题2
#!/usr/bin/env python3
# author:Alnk(李成果)
import os
"""
题目:用函数完成登录注册以及购物车的功能
需求:
1,启动程序,用户可选择四个选项:登录,注册,购物,退出。
2,用户注册,用户名不能重复,注册成功之后,用户名密码记录到文件中。
3,用户登录,用户名密码从文件中读取,进行三次验证,验证不成功则退出整个程序。
4,用户登录成功之后才能选择购物功能进行购物,购物功能(就是将购物车封装到购物的函数中)。
5,退出则是退出整个程序。
"""
# 设定登录标志位
login_flag = False
def register():
"""
注册
:return:None
"""
while 1:
username = input('\n请输入你想注册的账户名称>>>:').strip()
userpwd = input('请输入你想设置的登录密码>>>:').strip()
# 存储用户信息目录
if not os.path.exists("user_info"):
os.mkdir("./user_info")
if os.path.exists("user_info/%s" % (username)):
print("该用户名已经被注册,请重新输入\n")
continue
with open("user_info/%s" % (username), encoding='utf-8', mode='w') as f:
f.write("%s|%s|0" % (username,userpwd) )
f.flush()
print('账号注册成功!\n')
return
def login():
"""
登录
:return:None
"""
# 密码可输错次数
count = 3
while 1:
username = input("\n请输入登录账号(返回B/b)>>>:").strip()
if username.strip().lower() == 'b':
print('\n')
break
userpwd = input("请输入登录密码>>>:").strip()
# 用户是否存在
if os.path.exists('user_info/%s' % (username) ):
# 获取用户登录密码和密码输错次数
with open('user_info/%s' % (username), encoding='utf-8', mode='r') as f1:
user_l1 = f1.readline().strip().split('|')
pwd = str(user_l1[1])
count_pwd = int(user_l1[2])
# 账号是否冻结
if count_pwd == count:
print("账号 [%s] 已经被冻结,请联系管理员解除冻结或使用其他账号登陆\n" % (username))
continue
# 密码是否正确
if userpwd == pwd:
print('登录成功!\n')
# 重置密码输错次数
count_pwd = 0
user_l1[2] = count_pwd
with open('user_info/%s' % (username), encoding='utf-8', mode='w') as f2:
f2.write("%s|%s|%s" % (user_l1[0], user_l1[1], user_l1[2]))
f2.flush()
# 登录成功,修改默认的标志位
global login_flag
login_flag = True
return
else:
# 登录失败,密码输错次数 +1
count_pwd += 1
user_l1[2] = count_pwd
with open('user_info/%s' % (username), encoding='utf-8', mode='w') as f3:
f3.write("%s|%s|%s" % (user_l1[0] ,user_l1[1], user_l1[2]) )
f3.flush
# 密码连续输错3次,直接退出程序
if count_pwd == count:
exit('[%s] 账号密码连续输错3次,程序退出!' % (username))
print('密码错误。\n')
continue
else:
print('用户不存在!')
def recharge():
"""
充值
:return:True,用户余额
"""
while 1:
user_balance = input("请先给账号充值(返回B/b):")
if user_balance.lower() == "b":
print('')
return False
elif user_balance.isdigit():
user_balance = int(user_balance)
print("账号充值成功!余额为[%s]元\n" % (user_balance))
return True,user_balance
else:
print("输入有误,请重新输入。")
def jiesuan(user_shopping_cart,user_balance):
"""
结算功能
:param user_shopping_cart: 用户选购商品的临时字典
:param user_balance: 用户充值的余额
:return:None
"""
while 1:
# 显示购物车里的商品
print("\n您的购车里商品如下:")
for k in user_shopping_cart:
print("\t商品[%s] 数量[%s] 价格[%s]" % (k, user_shopping_cart[k]['number'], user_shopping_cart[k]['price']))
# 购物车所有商品总价
shopp_cart_total = 0
print("\n\n正在结算,请稍候...")
# 计算商品总价格
for k in user_shopping_cart:
shopp_cart_total = shopp_cart_total + user_shopping_cart[k]['number'] * user_shopping_cart[k]['price']
# 余额是否能够支付
if user_balance >= shopp_cart_total:
print("您本次总共需要支付[%s]元,余额为[%s]元" % (shopp_cart_total, user_balance))
print("\n您本次购买的商品详单如下:")
for k in user_shopping_cart:
print('\t商品[%s] 数量[%s] 价格[%s]'%(k,user_shopping_cart[k]['number'],user_shopping_cart[k]['price']))
print("\n本次总共消费[%s]元,账户余额为[%s]元" % (shopp_cart_total, user_balance - shopp_cart_total))
print("\n购买成功!\n")
return
else:
print("本次总共需要支付[%s]元 你的余额为[%s]元" % (shopp_cart_total, user_balance))
print("余额不足,请先删除购物车里的一些商品再去结算哟\n")
while 1:
print("\n购物车的商品列表如下:")
for k in user_shopping_cart:
print('\t商品[%s] 数量[%s] 价格[%s]' % (k, user_shopping_cart[k]['number'], user_shopping_cart[k]['price']))
user_choice2 = input("请输入你想删除的商品名称:")
# 从购物车删除商品
if user_shopping_cart.get(user_choice2):
# 商品数量为1,直接删除。否则减少商品的数量1
if user_shopping_cart[user_choice2]['number'] == 1:
del user_shopping_cart[user_choice2]
print('商品[%s]已从购物车删除' % (user_choice2))
elif user_shopping_cart[user_choice2]['number'] > 1:
user_shopping_cart[user_choice2]['number'] -= 1
print("商品[%s]数量减少1件" % (user_choice2))
break
else:
print("\n输入的商品名称有误,请重新输入")
def buy():
"""
购物
:return:None
"""
# 默认标志为是否被修改,即是否已经登录
if login_flag:
print('\n')
# 获取充值函数返回值,为一个元组(True,user_balance)
ret = recharge()
if ret[0]:
# 用户余额
user_balance = ret[1]
# 用户选购商品临时购物车
user_shopping_cart = {}
# 商品列表
goods_dic = {
"1": {"name": "电脑", "price": 1999, },
"2": {"name": "鼠标", "price": 10, },
"3": {"name": "键盘", "price": 60, },
"4": {"name": "手机", "price": 4000, },
"5": {"name": "ipad", "price": 2999, },
"n": {"name": "购物车结算", "price": '', },
}
while 1:
print("下列是您可以选购的商品(退出Q/q):")
for key in goods_dic:
print('\t', key, goods_dic[key]['name'], goods_dic[key]['price'])
user_choice = input("请输入你想购买的商品序号:")
if user_choice.lower() == "q":
print("退出购物商城")
break
# 结算
elif user_choice == "n":
jiesuan(user_shopping_cart,user_balance)
break
# 添加商品到用户购物车
elif goods_dic.get(user_choice):
# 判断购物车是否已经有该商品,如果有直接数量加1,没有则创建一个新的键值对
if user_shopping_cart.get(goods_dic[user_choice]['name']):
user_shopping_cart[goods_dic[user_choice]['name']]['number'] += 1
else:
user_shopping_cart[goods_dic[user_choice]['name']] = {"number": 1,"price": goods_dic[user_choice]['price']}
print("\n商品[%s] 价格[%s] " % (goods_dic[user_choice]['name'], goods_dic[user_choice]['price']))
print('添加到购物车成功!\n')
else:
print("输入有误,请重新输入哦\n")
else:
print('请先登录哦\n')
def sign_out():
"""
退出程序
:return:None
"""
exit('退出程序!')
def display():
"""
程序入口,显示
:return:None
"""
msg = """---- 欢迎来到老男孩购物商城 ----
1 注册
2 登录
3 购物
4 退出
"""
dic = {
'1': register,
'2': login,
'3': buy,
'4': sign_out,
}
while 1:
print(msg)
keys = input('请输入你要选择的操作序号>>>:')
if keys in dic:
dic[keys]()
else:
print('输入有误,请输入序号哟')
continue
if __name__ == '__main__':
display()
Python语言系列-03-文件操作和函数的更多相关文章
- Python基础-week03 集合 , 文件操作 和 函数详解
一.集合及其运算 1.集合的概念 集合是一个无序的,不重复的数据组合,它的主要作用如下 *去重,把一个列表变成集合,就自动去重了 *关系测试,测试两组数据之前的交集.并集.差集.子集.父级.对称差集, ...
- Python学习系列之文件操作
Pyhton文件打开方式 with= open('文件路径','打开模式') as f:#PS:python3提供了with语句来帮我们自动调用close方法,所以说无论打开文件是否出错都能自动正确的 ...
- C语言样式的文件操作函数
使用C语言样式的文件操作函数,需要包含stdio.h头文件. 1.打开文件的函数: //oflag的取值为“w”或“r”,分别表示以写或读的方式打开 FILE* fd = fopen(filename ...
- python 文件操作的函数
1. 文件操作的函数 open(文件名(路径), mode="?", encoding="字符集") 2. 模式: r, w, a, r+, w+, a+, r ...
- python 文件操作: 文件操作的函数, 模式及常用操作.
1.文件操作的函数: open("文件名(路径)", mode = '模式', encoding = "字符集") 2.模式: r , w , a , r+ , ...
- Unix/Linux环境C编程入门教程(41) C语言库函数的文件操作详解
上一篇博客我们讲解了如何使用Linux提供的文件操作函数,本文主要讲解使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #in ...
- Unix/Linux环境C编程新手教程(41) C语言库函数的文件操作具体解释
上一篇博客我们解说了怎样使用Linux提供的文件操作函数,本文主要解说使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #in ...
- php中文件操作常用函数有哪些
php中文件操作常用函数有哪些 一.总结 一句话总结:读写文件函数 判断文件或者目录是否存在函数 创建目录函数 file_exists() mkdir() file_get_content() fil ...
- PHP文件操作功能函数大全
PHP文件操作功能函数大全 <?php /* 转换字节大小 */ function transByte($size){ $arr=array("B","KB&quo ...
随机推荐
- Docker单机网络下
前言 Docker系列文章: 此篇是Docker系列的第七篇,大家一定要按照我做的Demo都手敲一遍,印象会更加深刻的,加油! 为什么要学习Docker Docker基本概念 Docker镜像基本原理 ...
- 1.3.4、通过Host匹配
server: port: 8080 spring: application: name: gateway cloud: gateway: routes: - id: guo-system4 uri: ...
- [开源名人访谈录] Philippe Gerum
译至:http://www.advogato.org/article/803.html 译者按:这篇采访的时间很早,但有助于你了解Xenomai相关的背景. 这是对菲利普格鲁姆,ADEOS项目的共同领 ...
- coretext简单使用
相对于UIKit,使用coretext绘制文本效率高,具有更高的自由度,可随时插入图片,增加文本点击事件等. 1.增加文本的点击事件 思路:定义UILabel子类,设置可点击的富文本range及其他属 ...
- python log装饰器
def log(func): #将原函数对象的指定属性复制给包装函数对象, 默认有 module.name.doc,或者通过参数选择 @functools.wraps(func) def wrappe ...
- 通过原生js实现数据的双向绑定
通过js实现数据的双向绑定 : Object.defineProperty了解 语法: Object.defineProperty(obj, prop, descriptor) obj 要定义属性的对 ...
- QT从入门到入土(三)——文件的读写操作
引言 文件的读写是很多应用程序具有的功能,甚至某些应用程序就是围绕着某一种格式文件的处 理而开发的,所以文件读写是应用程序开发的一个基本功能. Qt 提供了两种读写纯文本文件的基本方法: 用 QFi ...
- python+API接口测试框架设计(unittest)
1.测试框架简介 整个接口测试框架的设计图如下: basepage:存放的是公共的方法 common:存放的是自定义工具 data:存放的是公共动态数据,如BB.xls/ Id.md log:存放的是 ...
- Cannot read property 'data' of undefined —— 小程序开发
由于疫情原因目前处于半下岗状态,在家的时候就研究起了小程序开发.由于是新手,所以总会遇到各种问题,顺便记录一下. wx.showModal({ title: '提示', content: '这是一个模 ...
- 浅析VO、DTO、DO、PO的概念、区别和用处(八)
本篇文章主要讨论一下我们经常会用到的一些对象:VO.DTO.DO和PO. 由于不同的项目和开发人员有不同的命名习惯,这里我首先对上述的概念进行一个简单描述,名字只是个标识,我们重点关注其概念: 概念: ...