一、函数
什么是函数?
函数是可以实现一些特定功能的小方法或是小程序。在Python中有很多内建函数如:(print()),当然随着学习的深入,也可以学会创建对自己有用的函数。简单的理解下函数的概念,就是你编写了一些语句,为了方便使用这些语句,把这些语句组合在一起,给它起一个名字。使用的时候只要调用这个名字,就可以实现语句组的功能了,自己创建的函数就叫做自定义函数。
函数的特点:可重复使用的,用来实现单一,增强代码的重用性和可读性
定义函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
- 在函数中只要运行了return 下面的代码就不在执行直接返回!
语法:
def name(): #()里面内容称为形式参数 name为函数的名字 print() #中间的称为函数体 #没有return 默认返回值为None
调用函数:
前面定义函数的时候,都给函数取了个名字,调用函数格式就是 函数名字后面加个括号如:name()
实例:
1 #定义函数 2 def name(): 3 print("hello world") 4 5 #调用函数 6 name() 7 name()#第二次调用函数 8 9 #执行结果: 10 C:PythonPython35python.exe E:/Python课程/s13/day3/函数(返回值2).py 11 hello world 12 hello world
返回值实例:
1 def test():
2 print("a")
3 if 1 == 1: # 如果1等于2 才会执行下面的return
4 return True # 在函数里只要执行了return 下面的将不再执行 中断函数操作
5 return False #前面的条件不成立就会return False
6
7
8 name=test() #把函数的返回值赋予一个变量,这样就可以显示出来返回的结果
9 print(name)
给函数传递参数:
再说这个之前先说一下变量还在函数里面的使用;
首先定义全局变量的潜规则写法是全部大写与常亮一样。
所有参数(自变量)在Python里都是按引用传递。如果你在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。
如以下实例:
1 #执行 2 def name(li): #li就是给函数name传递一个参数,名为形参 3 li.append("a") #修改参数的里的内容,注意是修改,而不是重新赋值 4 print(li,type(li)) 5 6 lists=[1,2,3,"q"] #原始参数,定义成的变量 7 name(lists) #这里的lists 就是实际参数,统称实参 8 print(lists) 9 10 #返回结果: #反馈的结果就是把原始参数也改变了,下面的再有函数调用lists变量时,调的就是新生成的变量 11 C:PythonPython35python.exe E:/Python课程/s13/day3/函数(返回值2).py 12 [1, 2, 3, 'q', 'a'] <class 'list'> 13 [1, 2, 3, 'q', 'a'] 14 15 Process finished with exit code 0
global用法:
在函数里,要想给全局变量重新赋值,就用global如下:
1 #执行代码 2 name="tianjie" 3 def show(): 4 global name 5 name='alex' 6 print(name,type(name)) 7 show() 8 print(name) 9 10 #返回结果 11 C:PythonPython35python.exe E:/Python课程/s13/day3/函数(返回值2).py 12 alex <class 'str'> 13 alex 14 15 Process finished with exit code 0 16 17 #如果不加global name 只在函数作用域内生效 18 C:PythonPython35python.exe E:/Python课程/s13/day3/函数(返回值2).py 19 alex <class 'str'> 20 tianjie 21 22 Process finished with exit code 0
lambda表达式:
lambda 表达式,简单函数的表达方式
例如:
1 #例如定义一个函数: 2 3 # def test(a): 4 # b=a+1 5 # return b 6 # name=test(2) 7 # print(name) 8 9 #用lambda表达式写法 10 test=lambda a: a+1 11 #创建了形式参数a, 12 #函数内容,a+1 并把结果return 13 name=test(22) 14 print(name) 15 16 17 #结果就是:23
三元运算:
三元运算(三目运算),是简单的条件的语句缩写。
Python没有三目运算符但是可以用if else语句实现相同的功能:
#!/usr/bin/env python3 #三元运算格式 #test = 值1 if 条件 else 值2 #如果条件成立,那么值1赋值给变量test,否则将值2赋给test变量 #实例: test = True if 1 > 0 else False print(test) #运行结果 True
函数指定参数:
就是给函数传递多个参数,不用按照顺序形参对应实参,可以在实参里直接指定,要把实参赋值给哪个形参!
如下实例:
1 def show(name,name1): 2 print(name,name1) 3 show(name1=123,name=456)
默认参数:
默认形参等于一个值,如果调用函数是,没有给形参赋值,那么形参就用默认值;
如下实例:
# def show(name,name1=999): # #默认参数没有给name1赋值默认为999,默认参数必须放在后面 # print(name,name1) # # show("a1","a2") #如果赋值了就会把默认参数替换掉 #执行结果: a1 a2
函数发送邮件练习:
1 import smtplib 2 from email.mime.text import MIMEText 3 from email.utils import formataddr 4 5 #给不同人发邮件 6 7 def mail(user): #user 称为形式参数 8 test=True 9 try: 10 msg = MIMEText('邮件内容', 'plain', 'utf-8') 11 msg['From'] = formataddr(["tianjie",'zjht0709@sina.com']) 12 msg['To'] = formataddr(["gogo","451587411@qq.com"]) 13 msg['Subject'] = "主题" 14 15 server = smtplib.SMTP("smtp.sina.com", 25) 16 server.login("zjht0709@sina.com", "zjht0709") 17 server.sendmail('zjht0709@sina.com', [user,], msg.as_string()) 18 server.quit() 19 except Exception: 20 test=False 21 return test 22 test = mail("451587411@qq.com") #称为实际参数 23 test = mail("tianjie0522@163.com") #称为实际参数 24 25 if test: 26 print("发送成功") 27 else: 28 print("发送失败")
动态参数:
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做动态参数(*args,**kwargs)
形参一个*表示传递的是一个列表或者元组,两个**的表示字典,两个**的必须放在一个*后面,否则会报错,python默认的!
如下实例:
def show(*name):# 一个* 为元组 print(name,type(name)) show(1,2,3,4,5,) def show(**name): #两个*为字典 print(name,type(name)) show(k="v1",k2="v2") def show(*name,**name1): print(name,type(name)) print(name1,type(name1)) show("w1","w2",k="v1",k2="v2") #实参一个*的必须放在两个*的前面 #执行结果如下: C:PythonPython35python.exe E:/Python课程/s13/day3/函数(动态参数).py (1, 2, 3, 4, 5) <class 'tuple'> {'k2': 'v2', 'k': 'v1'} <class 'dict'> ('w1', 'w2') <class 'tuple'> {'k2': 'v2', 'k': 'v1'} <class 'dict'>
#传递变量形式
# def show(*name,**name1):
# print(name)
# print(name1)
# n=["a1","a2","a3"]
# w={"k1":"v1","k2":"v2"}
# show(*n,**w) #也可以传递列表或字典,意思是n前面加一个*,把n列表传递给*name
# #w前加两个*,把w字典传递给**name1
内置函数:
对于一些python中常用的函数,python自身就已经定义了一些函数用于调用,我们就叫它内置函数!
一些常用的内置函数具体用法:
1.abs();取绝对值
1 n=abs(-2) 2 print(n) 3 4 结果: 5 2
2.all();传入可迭代的对象中,都为真才为真;
Fasle: 0,None,"",[],{} ,()都为假
True: 1,-1,True," "
n=all([1,2,3," ",1,-1,True]) print(n) #结果 True
3.any() 传入可迭代的对象中,任意一个为真,返回真
n=any([0,None,"",[],{} ,()]) #都为假 print(n) #结果 False
4.bin() 把传入的十进制转换为二进制
n=bin(10) print(n) #执行结果 0b1010
5.oct() 把传入的十进制转换为八进制
1 n=oct(10) 2 print(n) 3 4 执行结果 5 0o12
6.hex() 把传入的十进制转换为十六进制
1 n=hex(10) 2 print(n) 3 4 执行结果 5 0xa
7.bytes() 把字符串转换成字节类型,需要指定编码
其中: gbk编码:一个汉字占2个字节;
utf8编码:一个汉字占3个字节
1 n=bytes("hello",encoding="utf-8") 2 print(n) 3 4 执行结果: 5 b'hello'
8.open()打开文件
f=open("db","r") # db是文件名,r 是文件模式
二、文件操作
上面已经说到了open这个python內键函数,就是为了打开文件,然后操作,最后关闭,这三步!
下面我们来看看,文件在python中有哪些操作方法;
打开文件:
1 f=open("db","r",encoding="utf-8")
#db:文件的路径加文件名字,r:文件模式,encoding :指定用什么字符编码打开
1、文件打开的模式:
r:只读模式,这个是默认的
w:只写模式,不可读 , 写之前会把原有的文件内容都给清空然后在写;慎用!慎用!
a:追加模式,可读,文件内有内容就在文件最后添加,没有就创建
x:Python3新增,如果文件存在,就报错,文件不存在创建并写文件;
“+”表示可同时读写文件
r+: 可读,可写,可追加
w+:写读
a+:同a
“b”表示处理二进制文件
在Python内部打开文件的时候,python自己是把文件内容以二进制文件打开的,然后通过python解释器再转换成字符编码,写入文件的时候也是一样,需要通过python解释器做翻译成二进制方式给电脑
rb:以二进制方式读取
wb:以二进制方式写,不用再通过python解释器作解释了,读的时候也必须是以二进制方式读取
ab:以二进制方式追加
文件的操作方法:
1 def close(self, *args, **kwargs): # real signature unknown 2 '''关闭文件''' 3 pass 4 5 6 def fileno(self, *args, **kwargs): # real signature unknown 7 '''文件描述''' 8 pass 9 10 def flush(self, *args, **kwargs): # real signature unknown 11 '''刷新文件内部缓冲区''' 12 pass 13 14 def isatty(self, *args, **kwargs): # real signature unknown 15 '''判断文件是否是同意tty设备?''' 16 pass 17 18 def read(self, *args, **kwargs): # real signature unknown 19 '''读文件,指定字节数据''' 20 pass 21 22 def readable(self, *args, **kwargs): # real signature unknown 23 '''是否可读''' 24 pass 25 26 def readline(self, *args, **kwargs): # real signature unknown 27 '''仅读取一行''' 28 pass 29 30 def seek(self, *args, **kwargs): # real signature unknown 31 '''指定文件中指针的位置''' 32 pass 33 34 def seekable(self, *args, **kwargs): # real signature unknown 35 '''指针是否可操作''' 36 pass 37 38 def tell(self, *args, **kwargs): # real signature unknown 39 '''获取指针位置''' 40 pass 41 42 def truncate(self, *args, **kwargs): # real signature unknown 43 '''截断数据,仅保留指定之前的数据''' 44 pass 45 46 def writable(self, *args, **kwargs): # real signature unknown 47 '''是否可写''' 48 pass 49 50 def write(self, *args, **kwargs): # real signature unknown 51 '''写内容''' 52 pass
1 f.read([size]) #size为读取的长度,打开模式有b 就按byte为单位,无b就以字符为单位 2 3 f.readline([size]) #读第一行 4 f.readlines([size]) #把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数,size是表示读取内容的总长,也就是说可能只读到文件的一部分。 5 6 f.write(str) #把str写到文件中,write()并不会在str后加上一个换行符 7 8 f.writelines(seq) #把seq的内容全部写到文件中(多行一次性写入)。这个函数也只是忠实地写入,不会在每行后面加上任何东西。 9 10 f.close() #关闭文件。 11 12 f.flush() #把缓冲区的内容写入硬盘 13 f.tell() #返回文件操作标记的当前位置,以文件的开头为原点 14 f.next() #返回下一行,并将文件操作标记位移到下一行。把一个file用于for … in file这样的语句时,就是调用next()函数来实现遍历的。 15 16 f.seek(offset[,whence]) #将文件打操作标记移到offset的位置。这个offset一般是相对于文件的开头来计算的,一般为正数。但如果提供了whence参数就不一定了,whence可以为0表示从头开始计算,1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。需要注意,如果文件以a或a+的模式打开,每次进行写操作时,文件操作标记会自动返回到文件末尾。 17 18 f.truncate([size]) #把文件裁成规定的大小,默认的是裁到当前文件操作标记的位置。如果size比文件的大小还要大,依据系统的不同可能是不改变文件,也可能是用0把文件补到相应的大小,也可能是以一些随机的内容加上去。
具体用法如下:
1 f=open('db','r') 2 data=f.read(1) #读取文件如果读取模式无b,按一个字符读取,不指定,默认是全部 3 print(data,type(data)) 4 f.close() 5 6 f=open("db","w") #写文件,写之前会把“db”文件中的内容清空然后再写 7 f.write("hello") 8 f.close() 9 10 f=open("db","a") #追加在文件后面 11 f.write("tianjie") 12 f.close() 13 14 f=open("db1","x") #如果文件存在就会报错,不存在创建且写入 15 f.write("hi") 16 f.close() 17 18 #字节方式打开 19 20 f=open('db','rb') #读取模式有b,则read,按照字节读取 21 data=f.read() 22 print(data,type(data)) 23 f.close() 24 25 f=open("db","ab") #以二进制方式追加且指定字符加,因为有b 是以字节方式追加的,所以需要把字符转化成字节 26 f.write(bytes("田杰",encoding='utf-8')) 27 f.close() 28 29 f = open('db','wb') #字符需要转换成字节 30 test = "人民的力量" 31 bytes_data = bytes(test,encoding='utf-8') 32 # f.write(bytes("人民的力量",encoding='utf-8')) 33 f.write(bytes_data) 34 f.close() 35 36 #+号 37 f=open("db","r+") #读、写 这个通常用的较多 38 f.read(1) #堆取第一个字符 39 print(f.tell()) #查看当前指针所在的位置(字节) 40 f.seek(f.tell()) #调整当前指针位置 41 f.write("333") #在调整后的指针位置后面添加 42 print(f.tell()) 43 44 f=open("db","w+") #写读,先清空,然后再写,再写之后的就可以读了 45 f.write("tianjie") 46 n=f.tell() 47 print(n) 48 f.seek(0) #从头开始读,把指针调到最开始位置(0),从指针第0个位置开始读 49 data=f.read() 50 print(data)
for line in f.readlines() : #读取每一行内容,
print(line)
line.startswith("xxxx") #以xxxx字符串开头的行
f.readline(): #读取第一行内容
with .... as .....:
文件打开方式还有一种就是用with as 的方式,这种方式的好处就是,你不用自己手动再去关闭文件了,这种方式自动就会关闭文件。
具体用法:
1 with open("db","r+") as f: #打开模式都是一样的写法,(注意缩进) 2 for i in f.readlines(): 3 print(i)
同时打开多个文件:
1 #同时打开两个文件,把一个文件中的内容,写到另一个文件中 2 with open("db","r") as f,open("db2","w") as k: 3 for line in f.readlines(): 4 k.write(line)