1.函数
==============第一个函数=================
def fun1():
# this is my first function
print('Hello Function!')
return 0
---》》第一个函数,def定义函数,无参数,返回值为0,打印‘Hello Function’
==============第一个过程=================
def proce1():
# this is my first procedure
print('Hello Procedure')
---》》函数和过程的区别是,过程没有返回值。。。函数也可以没有返回值啊?擦!咋区别?
==============函数的返回值=================
'''
函数返回值:
1.无return,返回none
2.return一个值,返回object(值本身,python所有值都可以看作一个对象)
3.return多个值,返回一个tuple
为什么要有返回值:
我想要整个函数执行的结果,后面的程序需要根据这个执行结果进行不同的操作
'''
# 无返回值
def test_none():
print('this is test_none'.ljust(50,'-'))
#返回值为0
def test_num():
print('this is test_num'.ljust(50,'-'))
return 0
#返回一个tuple
def test_tuple():
print('this is test_tuple'.ljust(50,'-'))
return 3,'champions',[1,'中金所','随便'],{'name':'yang','age':'secret'}
#此为高阶函数,返回要给函数
def test_high():
print('this is test_high'.ljust(50,'-'))
return test_num #返回test_num函数的内存地址
print(test_none())
print(test_num())
print(test_tuple())
print(test_high())
==============局部变量与全局变量=================
school='天庭' #全局变量,全局生效
def change_name(name):
print('Before change:',name)
school='花果山' #局部变量,函数内生效
print('Local variable:',school)
name='齐天大圣' #局部变量,调用函数时,实现改名字功能
print('After change:',name)
name='孙悟空' #全局变量
change_name(name)
print('Global variable:',school)
=============需要传参的函数=================
def func_arg(x,y):
print(x,y)
#func_arg(1,2)
#func_arg(1) #func_arg() missing 1 required positional argument: 'y'
# func_arg(1,2,3) #func_arg() takes 2 positional arguments but 3 were given
'''
x=1 #此x为实参,换成a=1,会不会直观点,哈哈
y=2 #次y为实参,换成b=2,会不会直观点,哈哈
func_arg(x=x,y=y)
'''
#func_arg(1,2) #位置参数调用,与形参位置一一对应
#func_arg(y=1,x=2) # 关键字参数调用,与形参位置无关
#func_arg(x=1,2) #不可以,positional argument follows keyword argument
#func_arg(1,y=2) #可以,关键字参数必须在最后
#func_arg(1,x=2) #不可以,x有多个值,test1() got multiple values for argument 'x'
'''
def test1(x,y,z):#形参
print(x)
print(y)
print(z)
#test1(1,y=2,3) #不可以,positional argument follows keyword argument
test1(1,2,z=3) #可以
test1(3,z=6,y=9) #可以
'''
===============需要传参的函数,参数带默认值================
'''
default argument特点:
1.调用函数的时候,默认参数可不传
应用场合:
1.默认安装
2.数据库链接字符串
'''
def test1(x,y=2):
print(x)
print(y)
#test1(1)
#test1(1,y=3)
#test1(1,3)
===============一个函数,若参数数目不固定,则使用参数组================
'''
针对形参数量不固定,下面隆重介绍:参数组
'''
# def test1(*args): #接收N个位置参数,转换成元组的方式,不能接受关键字参数
# print(args) #封装为元组
# #print(*args) #不封装
#
# test1(1,2,3,4,5) #多个实参放到一个元组里
# test1([7,8,9,0]) #列表作为元组的一个元素
# test1(*[7,8,9,0]) #同多个实参放到一个元组里
# test1({'name':'weixiaobao','age':16},1,2) #字典作为元组的一个元素
# def test2(x,*args):
# print(x)
# print(args) #参数封装成元组输出
#
# test2(1,2,3,4,5,6)
#字典
#把N个关键字参数转换成字典的方式
# def test3(**kwargs): #接受关键字参数,转换成字典方式
# print(kwargs)
# print(kwargs['name'])
# print(kwargs['age'])
# print(kwargs['sex'])
# test3(name='bajie',age=500,sex='f')
# test3(**{'name':'bajie','age':500,'sex':'f'})
#综合使用
# def test4(organization,**kwargs):
# print(organization)
# print(kwargs)
#test4('tianting',name='neza',age=300,sex='x') #完美传参
#test4('diyu') #最懒传参,字典为空
#test4('renjian',6) #错误传参,test4() takes 1 positional argument but 2 were given
#终极综合使用
# def test5(organization,position,*args,**kwargs): #参数组一定要往后放
# print(organization)
# print(position)
# print(args)
# print(kwargs)
#test5('tianting','33tian',1,2,3,name='change',age=18) #完美调用
#test5('renjian','saodi') #最懒调用,元组和字典都为空
#一个函数中引用其他函数
# def test6(organization,position=33,*args,**kwargs):
# print(organization)
# print(position)
# print(args)
# print(kwargs)
# logger('test6')
# def logger(source):
# print('from %s',source)
# test6('diyu')
#接下来给你一个错误示例
# def test6(organization,position=33,*args,**kwargs):
# print(organization)
# print(position)
# print(args)
# print(kwargs)
# logger('test6')
# test6('diyu') #name 'logger' is not defined,从上到下执行,此时logger还未定义
# def logger(source):
# print('from %s',source)
#最最最使用传参方式,随你咋搞都不报错
def test7(*args,**kwargs):
print(args)
print(kwargs)
test7()
test7(1)
test7(name='wukong')
test7(1,name='wukong')
===============高阶函数,初识================
#higher order function
# ads 内置函数
def add(a,b,f):
print(a)
print(b)
return f(a)+f(b)
res=add(2,3,abs)
print(res)
===============递归函数================
'''
recursion,递归函数
1.必须要有个明确的结束条件
2.每次进入更深一层时,问题规模相对上次都应有所减少
3.递归效率不高,递归层次过多会导致栈溢出
'''
def recur_calc(n):
print(n)
if int(n/2)>0:
return recur_calc(n/2)
print('--->>',n)
recur_calc(10)
===============函数尾声================
'''
函数优点:
1.代码重用
2.程序容易扩展
3.代码一致性
'''
import time
def addlog():
time_format='%Y-%m-%d %X'
time_current=time.strftime(time_format)
with open('log','a+',encoding='utf-8') as f:
f.write('%s this is used add log...\n' %time_current)
def test1():
print('this is test1')
addlog()
def test2():
print('this is test2')
addlog()
test1()
test2()
2.集合(set)
list_1=[1,3,5,7,9]
list_1=set(list_1)
list_2=[2,4,6,8,9,0]
list_2=set(list_2)
print(list_1,list_2)
#交集
print('交集intersection方法:',list_1.intersection(list_2))
print('交集\'&\'运算符:',list_1 & list_2)
#并集
print('并集union方法:',list_1.union(list_2))
print('并集\'|\'运算符:',list_1 | list_2)
#差集
print('差集difference方法1-2:',list_1.difference(list_2)) #in list_1 but not in list_2
print('差集difference方法2-1:',list_2.difference(list_1)) #in list_2 but not in list_1
print('差集\'-\'运算符1-2:',list_1-list_2)
#子集
list_3=set([1,3,5])
print('list_3是list_1的子集:',list_3.issubset(list_1)) #list_3是list_1子集
print('list_1是list_3的父集:',list_1.issuperset(list_3))
#对称差集
print('对称差集symmetric方法:',list_1.symmetric_difference(list_2)) #去掉交集元素
print('对称差集\'^\'运算符:',list_1 ^ list_2)
print('----------------------')
list_4=set([5,6,7,8])
print(list_3.isdisjoint(list_4)) #return True if tow sets have a null intersection.
# 添加一项
list_1.add('222')
print(list_1)
# 添加多项
list_1.update([555,666,777])
print(list_1)
# 删除一项
list_1.remove('222')
print(list_1)
# set的长度
print(len(list_1))
# 判断元素是否在集合中
if 666 in list_1:
print('666 is a element of set!')
if 222 not in list_1:
print('222 is not a element of set!')
# 浅copy
list_1_copy=list_1.copy()
print('list_1的浅copy:',list_1_copy)
3.文件操作
==============先来个Example,登录=================
'''
通过读取文件的方式登陆,文件格式如下:
sunwukong,swk123
zhubajie,zbj123
jiabaoyu,jby123
'''
usernames=[]
passwords=[]
fobj=open('login.txt','r')
username=input('username:')
password=input('password:')
while True:
lines=fobj.readline().strip()
if not lines:
break
t_names,t_pwds=[str(s) for s in lines.split(',')]
usernames.append(t_names)
passwords.append(t_pwds)
if username in usernames:
pwd_index=usernames.index(username)
if password==passwords[pwd_index]:
print('welcome login...')
else:
print('Invalid password!')
else:
print('User non-exsitent!')
==============步步推进,先来个简单的文件opration吧=================
1. Somehow, it seems the love I knew was always the most destructive kind
2. 不知为何,我经历的爱情总是最具毁灭性的的那种
3. Yesterday when I was young
4. 昨日当Alex年少轻狂
5. The taste of life was sweet
6. 生命的滋味是甜的
7. As rain upon my tongue
8. 就如舌尖上的雨露
9. I teased at life as if it were a foolish game
10. 我戏弄生命 视其为愚蠢的游戏
---》》以上为文件的内容
f=open('song','r',encoding='utf-8') #打开文件,以只读的方式,采用‘utf-8’编码(操作系统默认gbk)
first_line=f.readline() #读取第一行
print(first_line)
second_line=f.readline() #读取第二行
print(second_line)
third_line=f.readline() #读取第三行
print(third_line)
print('我是分割线'.center(50,'-'))
data=f.read() #读取剩下的全部,文件大时不要用
print(data)
f.close() #关闭文件
---》》试试f.read()后,再使用f.read()或者f.readlines(),打印出结果,看看会发生什么。
==============向前走,先来看9种操作模式的前3式(r,w,a)=================
# file opr
# r:只读
# w: 只写
# a: 追加
# with open('song','r',encoding='utf-8') as f:
# line=f.readline() #读取一行
# data=f.read() #读取剩下的全部
# lines=f.readlines() #啥也都不到,只剩一个空列表
# print(line)
# print(data)
# print(lines)
# with open('song','w',encoding='utf-8') as f:
# str='自在飞花轻似梦,无边丝雨细如愁'
# f.write(str) #删除文件原有内容,写入str内容,慎重使用!!!
# with open('song','a',encoding='utf-8') as f:
# str='\n自在飞花轻似梦,无边丝雨细如愁'
# f.write(str) #在原有内容末尾添加
==============继续走,再来看9种操作模式的中间3式(r+,w+,a+)=================
# file opr
# r+ 可读、可写,文件若不存在,则报IOError
# w+ 写读,首先创建一个新文件,再在新文件中写
# a+ 追加读写
# with open('song','r+',encoding='utf-8') as f:
# ############ read ############
# # line=f.readline()
# # print(line)
# # data=f.read()
# # print(data)
# # lines=f.readlines()
# # print(lines)
# ############ write ############
# str = '噫嘘唏!蜀道难,难于上青天!'
# f.write(str) #写入时,使用str从头开始替换原文件内容
# with open('song','w+',encoding='utf-8') as f: #写读,如果文件不存在就创建一个
# str='自在飞花轻似梦,无边丝雨细如愁'
# f.write(str) #清空原有内容,然后写入str
# data=f.read() #明明有内容,为啥都出来为空?有毛用!!!
# print(data)
# with open('song','a+',encoding='utf-8') as f: #a+w 可写,可追加,文件不存在就创建
# data=f.read()
# print(data) #读不出来,不可读?
# str = '\n自在飞花轻似梦,无边丝雨细如愁'
# f.write(str) #追加可以
==============最后走,再来看9种操作模式的最后3式(rb,wb,ab)=================
# file opr
# rb:读二进制文件
# wb:写二进制文件
# ab: 追加二进制文件
# with open('song','rb') as f: #二进制读
# line=f.readline()
# print(line) #打印出的结果以b打头,代表bytes类型
# with open('song','wb') as f: #二进制写
# binary='Hello Binary'.encode() #字符串转换为二进制
# f.write(binary)
with open('song','ab') as f: #二进制追加
# line=f.readline() #好吧,次模式不支持和read,报“io.UnsupportedOperation: read”
# print(line)
binary='自在飞花轻似梦,无边丝雨细如愁'.encode()
f.write(binary) #追加到源文件内容末尾
==============以为只有9中,你错了骚年,再来看(rb+,wb+,ab+)=================
pass
==============模式汇总=================
'''
模式 描述
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
'''
==============文件的循环读取=================
# 循环读取
# 第一种简单循环
# with open('song','r',encoding='utf-8') as f:
# for line in range(5):
# print(f.readline())
# 转换为列表,使用readlines方法
# with open('song','r',encoding='utf-8') as f:
# for line in f.readlines(): #readlines 列表,每行为一个列表元素,相当于循环读取一个列表
# print(line.strip())
# 可以表示每行的序号,以0开始
# with open('song','r',encoding='utf-8') as f:
# data=f.readlines()
# for index,line in enumerate(data):
# # print(index,line.strip())
# if index==5:
# print('我是分割线'.center(50,'-'))
# print(line.strip())
# hign bg 效率最高,f变为迭代器
# with open('song','r',encoding='utf-8') as f:
# count = 0
# for line in f:
# if count == 5:
# print('我是分割线'.center(50, '-'))
# count += 1
# #break
# continue
# print(line.strip())
# count += 1
==============文件的修改=================
#使用此方式无法修改
# with open('song','r+',encoding='utf-8') as f:
# if f.readable() and f.writable():
# print(f.readline().strip())
# print(f.readline().strip())
# f.write('-----噫嘘唏,蜀道难,难于上青天!------') #想在第二行后插入,结果追加到了末尾
# print(f.readline().strip())
# print(f.tell()) #统计打印了多少个字符
# f.seek(10) #指针回到第十个字符后
# print(f.tell())
# print(f.readline().strip()) #从第10个字符后,开始打印
---》》以上方式无法修改
==============只好用以下方式修改=================
'''
# 修改一个文件
1.像vim一样,先将文件加载到内存里,修改完成后,写回到硬盘
2.打开一个文件A-read,再打开一个文件B-write,将A-read文件的内容逐行写入的B-write,
当遇到A-read中需要修改的内容时,直接将修改的内容写入到B-write,A-read中内容不变,然后
接着将A-read中后续内容,写入到B-write.
'''
with open('song_read','r',encoding='utf-8') as f_read:
with open('song_write','w',encoding='utf-8') as f_write:
str='昨日当Alex年少轻狂'
if f_read.readable():
for line in f_read:
if str in line:
line=line.replace(str,'昨日当wo年轻狂')
f_write.write(line)
else:
print('song_read is not readable')
---》》with打开两个文件,一个用于读取,一个用于写入;
---》》一行行,边读边写,检索到需要修改的行后(if str in line),修改内容后写入
---》》line.replace()进行修改
==============文件的常用方法=================
'''
各种方法--->>
# tell方法:read后,返回读取到的字符数
# seek方法:seek(0),返回到最前,光标定位0个字符后
print(f.tell())
print(f.readline().strip())
print(f.readline().strip())
print(f.readline().strip())
#print(f.read(50)) #读取50个字符,无法确定行数
print(f.tell()) #返回读取到的字符数
print(f.seek(0)) #返回第一行,只能返回到第一行,试试seek(10),前10个字符不会打印
print(f.readline()) #打印返回后的行
# encoding,打印文件的编码格式
print(f.encoding)
# 文件编号,操作系统编的。。。
print(f.fileno())
# 是否为终端设备,跟打印机等交互的时用
print(f.isatty())
# 不是所有的文件都可以seek的,像终端文件就无法seek
print(f.seekable())
# 判断文件是否可读
print(f.readable())
# 判断文件是否可写
print(f.writable())
==============flush方法,写入硬盘=================
# flush刷新,写入硬盘
>>> f=open('test.txt','w')
>>> f.write('hello1\n')
7
>>> f.flush()
>>> f.write('hello2\n')
7
>>> f.flush()
>>>