Python 函数
函数式编程和面向对象编程
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
面向对象:对函数进行分类和封装
函数式编程最重要的是增强代码的重用性和可读性
定义函数
def
函数名([参数]):
...
函数体
...
return
返回值
- def:定义函数的关键字
- 函数名:函数的名称,指向函数的内存地址(解释器将函数放在内存中,直到调用函数时才执行函数)
- 函数体:函数中进行一系列的逻辑计算
- 参数:为函数体传递的数据,参数可以0或多个
- 返回值:函数执行完毕返回给调用者的数据,可以返回多个。(函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。)
调用函数(执行函数):function([参数])
函数返回值
获取返回值:value=function([参数])
如果函数没有定义return语句, 默认返回None
函数体内部的语句在执行时,一旦执行到return
时,函数就执行完毕,后面的语句不会被执行,并将结果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。
如:
def show():
print('a')
if 1 == 1:
return True
print('b') -- 'b'不会被打印
返回值的应用: 可根据return值如True or False 来确定重试次数
函数的参数
形参(形式参数):定义函数时参数的名称
实参(实际参数):调用函数时实际传入的值
- 位置参数:可以有1个或多个,调用函数时,传入的值按照位置顺序依次赋给参数
#计算x的n次方
def power(x, n): # x,n 分别是形式参数 s = 1 while n > 0: n = n - 1 s = s * x return s>>> power(5, 2) # 5,2是实际参数
25
>>> power(n=2,x=5) # 也可以不按顺序指定参数
- 默认参数:降低调用函数的难度(注意默认参数可以有多个,但必须放在最后,且必须指向不可变对象)
def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s
>>>power(5) # 没有传递第二个参数,默认计算x的平方
25
def add_end(L=[]): # 默认指向可变对象时调用会有问题
L.append('END')
return L
>>> add_end()
['END']
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
- 动态参数: *arg , **arg(关键字参数)
def show(*arg): print(arg,type(arg))
>>> show(1,'a',[2,'b']) # 函数内部,把传入的参数转化成元组,调用该函数时,可以传入任意个参数
(1, 'a', [2, 'b']) <class 'tuple'>
>>> ls=[1,'a',[2,'b']]
>>> show(ls) # 把ls 整体作为一个参数传入
([1, 'a', [2, 'b']],) <class 'tuple'>
>>> show(*ls) # *ls 把 ls 内的元素作为多个参数传入,注意两者的区别。
(1, 'a', [2, 'b']) <class 'tuple'>
关键字参数
def show(**arg):
print(arg,type(arg))
>>> show(k1=1,k2='a',k3=[2,'b']) # 函数内部,将传入的参数自动组装为一个字典,调用该函数时,可以传入任意个参数(key=value)
{'k1': 1, 'k2': 'a', 'k3': [2, 'b']} <class 'dict'>
>>> dc={'k1':1,'k2':'a','k3':[2,'b']}
>>> show(**dc) # 将字典内的元素作为多个参数传入
{'k1': 1, 'k2': 'a', 'k3': [2, 'b']} <class 'dict'>
动态参数组合:
def show(*args,**kwargs): # ** 放后面
print(args,type(args))
print(kwargs,type(kwargs))
>>> show(1,2,3, k1=1,k2='a') # 注意传参顺序
(1, 2, 3) <class 'tuple'>
{'k1': 1, 'k2': 'a'} <class 'dict'>
>>> ls=[1,2,3]
>>> dc={'k1':1,'k2':'a'}
>>> show(ls,dc)
([1, 2, 3], {'k1': 1, 'k2': 'a'}) <class 'tuple'>
{} <class 'dict'>
>>> show(*ls,**dc)
(1, 2, 3) <class 'tuple'>
{'k1': 1, 'k2': 'a'} <class 'dict'>
匿名函数:lambda 表达式
匿名函数故名思议就是没有名字的函数,它是一种简单函数的简单表示方式,就像三元运算是简单条件判断的简单表示。但可以把匿名函数赋值给一个变量,利用变量来调用该函数。
例如:func=lambda a: a+1 (a是形式参数)
等价于:
def func(a)
return a+1
匿名函数只能有一个表达式,不用写return
,返回值就是该表达式的结果。
使用函数编写发送邮件小程序:
不带参数
#!/usr/bin/env python
import smtplib from email.mime.text import MIMEText from email.utils import formataddr def testmail(): ret=True try: msg=MIMEText('Test python','plain','utf-8') msg['From']=formataddr(['wubo1','bobo199169@163.com']) msg['To']=formataddr(['wubo2','634267647@qq.com']) msg['Subject']='theme' server=smtplib.SMTP_SSL('smtp.163.com',465) server.login('bobo199169@163.com','password') server.sendmail('bobo199169@163.com',['634267647@qq.com',],msg.as_string()) server.quit() except Exception: ret = False return ret set=testmail() if set: print('send success') else: print('send faild')
带参数
#!/usr/bin/env python
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
def testmail(user):
ret=True
try:
msg=MIMEText('Test python','plain','utf-8')
msg['From']=formataddr(['wubo1','bobo199169@163.com'])
msg['To']=formataddr(['wubo2',user])
msg['Subject']='theme'
server=smtplib.SMTP_SSL('smtp.163.com',465)
server.login('bobo199169@163.com','password')
server.sendmail('bobo199169@163.com',[user,],msg.as_string())
server.quit()
except Exception:
ret = False
return ret
set=testmail('2387829946@qq.com') # 指定给2387829946@qq.com 发送邮件
if set:
print('send success')
else:
print('send faild')
注意:使用SMTP_SSL登录邮箱,在邮箱设置授权码,否则使用smtplib.SMTP登录会抛如下异常
Traceback (most recent call last):
....
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed