day-08函数

1、什么是函数?
在程序中,函数就是具备某一功能的工具,事先将工具准备好即函数的定义,遇到应用场景拿来就用即函数的调用,所以务必记住:#函数的使用必须遵循先定义,后调用的原则

2、为何要用函数,不用函数问题是:

  1、程序冗长
  2 程序的扩展性差
  3 程序的可读性差

3 、如何用函数:
函数的使用必须遵循先定义,后调用的原则

如何定义函数:

 def 函数名(参数1,参数2,...):
     '''
     函数功能的描述信息
     :param 参数1: 描述
     :param 参数2: 描述
     :return: 返回值
     '''
     代码1
     代码2
     代码3
     ...
     return 返回值 #可有返回值可没有返回值,遇到return函数执行结束
 1 def register():
 2     while True:
 3         uname=input('username>>:').strip()
 4         if uname.isalpha():
 5             break
 6         else:
 7             print('用户名必须由字母组成傻叉')
 8     while True:
 9         pwd1=input('密码>>: ').strip()
10         pwd2=input('重复输入密码>>: ').strip()
11         if pwd1 == pwd2:
12             break
13         else:
14             print('两次输入的密码不一致,眼瞎吗')
15     with open('db.txt','at',encoding='utf-8') as f:
16         f.write('%s:%s\n' %(uname,pwd1))
17         f.flush() #立即刷入文件内容
18 
19 def auth():
20     认证功能
21     inp_uname=input('请输入你的账号:').strip()
22     inp_pwd=input('请输入你的密码:').strip()
23     with open('db.txt','rt',encoding='utf-8') as f:
24         for line in f:
25             info=line.strip('\n').split(':')
26             if inp_uname == info[0] and inp_pwd == info[1]:
27                 print('login successfull')
28                 break
29         else:
30             print('账号或密码错误')
View Code
 

(1)函数定义阶段:只检测函数体的语法,不执行函数体代码
def func():
print('1111')
print('222')
print('333')

func()

错误调用步骤

 1  (1 2 def foo():
 3      print('from foo')
 4      bar()
 5  def bar():
 6      print('from bar')
 7  foo()
 8 (2 9  def bar():
10      print('from bar')
11 
12  def foo():
13      print('from foo')
14      bar()
15 
16  foo()
17 (3)#错误代码
18 def foo():
19      print('from foo')
20      bar()
21 foo()
22  def bar():
23      print('from bar')
View Code

 二、函数的参数

(1)无参函数:

在函数定义阶段括号内没有参数,称为无参函数
注意:定义时无参,意味着调用时也无需传入参数
应用:
如果函数体代码逻辑不需要依赖外部传入的值,必须定义无参函数
def func():
print('hello world')
func()

(2)有参函数

在函数定义阶段括号内有参数,称为有参函数
注意:定义时有参,意味着调用时也必须传入参数
应用:
如果函数体代码逻辑需要依赖外部传入的值,必须定义成有参函数

 1 def sum2(x,y):
 2       x=10
 3       y=20
 4      res=x+y
 5      print(res)
 6  sum2(10,20)
 7  sum2(30,40)
 8 
 9 def check_user():
10     while True:
11         uname=input('username>>:').strip()
12         if uname.isalpha():
13             return uname
14              break
15         else:
16             print('用户名必须由字母组成傻叉')
17 
18 def check_pwd():
19     while True:
20         pwd1=input('密码>>: ').strip()
21         pwd2=input('重复输入密码>>: ').strip()
22         if pwd1 == pwd2:
23             return pwd1
24         else:
25             print('两次输入的密码不一致,眼瞎吗')
26 
27 def db_hanle(uname,pwd1):
28     with open('db.txt','at',encoding='utf-8') as f:
29         f.write('%s:%s\n' %(uname,pwd1))
30          f.flush()
31 
32 def register():
33      #检测用户名是否合法
34      x=check_user() x='EGON'
35     #检测密码是否合法
36      y=check_pwd() y='123'
37      #写入数据文件
38      db_hanle(合法的用户名,合法的密码)
39      db_hanle(x,y)
40 register()
View Code

(3)空函数(主要用来前期搭建逻辑框架思维)

1  def func():
2      pass
3  def check_user():
4      pass
5  def check_pwd():
6      pass
7  def write_db(x,y):
8      pass
View Code

三、函数的返回值

1、什么是返回值?

返回值是一个函数运行结束后的处理结果

2、为什么要有返回值?

如果我们需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须有返回值

3、函数的返回值的应用
函数的返回值用return去定义
格式为:
return 值

注意:
1、return是一个函数结束的标志,函数内可以有多个return,但只要执行一次,整个函数就会结束运行

2、return 的返回值无类型限制,即可以是任意数据类型

3、return 的返回值无个数限制,即可以用逗号分隔开多个任意类型的值
  0个:返回None,ps:不写return默认会在函数的最后一行添加return None
  1个:返回的值就是该值本身
  多个:返回值是元组

四、函数的调用

1 什么是调用函数?

函数名(...)即调用函数,会执行函数体代码,直到碰到return结束或者一直运行完毕所有代码

2 为何要调用函数?

调用函数的目的就是为了调用用函数的功能

总的分类:
  1、形参:在函数定义阶段括号内定义的参数,称之为形式参数,简称形参,本质就是变量名
  2、实参:在函数调用阶段括号内传入的值,称之为实际参数,简称实参,本质就是变量的值

详细的分类:
一、位置参数:
位置形参:在函数定义阶段,按照从左到右的顺序依次定义的形参,称之为位置形参
特点:但凡是按照位置定义的形参,都必须被传值,多一个不行,少一个也不行

def foo(x,y):
  print('x:',x)

位置实参:在函数调用阶段,按照从左到右的顺序依次定义的实参,称之为位置实参
特点:按照位置为对应的形参依次传值

def foo(x,y):

  foo(1,2)
  foo(2,1)

二、关键字实参:在调用函数时,按照key=value的形式为指定的参数传值,称为关键字实参

特点:可以打破位置的限制,但仍能为指定的形参赋值

def foo(x,y):
     foo(1,y=2,x=10)

三:默认参数:在函数定义阶段,就已经为形参赋值,该形参称为默认形参,特点:在定义阶段就已经被赋值,意味着在调用可以不用为其赋值

def foo(x,y=10):
    print('x:',x)
    print('y:',y)
    foo(1)   #不赋值 默认为10
    foo(1,3)  #赋值为新的数值3

 注意:

  1、位置形参必须放到默认形参的前面,否则报语法错误

  2、默认参数的值只在定义阶段赋值一次,即默认参数的值在函数定义阶段就已经固定死了

  3、默认参数的值通常应该定义不可变类型

 1 1(错误事例)
 2 def register(name,hobby,hobbies=[]):
 3      hobbies.append(hobby)
 4      print('%s的爱好' %name,end=':')
 5      print(hobbies)
 6 
 7  register('isetan','play')
 8  register('axxx','piao')
 9  register('lxx','烫头')
10 
11 2(正确方法)
12 
13 def register(name,hobby,hobbies=None):
14      if hobbies is None:
15          hobbies=[]
16      hobbies.append(hobby)
17      print('%s的爱好' %name,end=':')
18      print(hobbies)
19 
20  register('isetan','play')
21  register('axxx','piao')
22  register('lxx','烫头')
View Code

四:可变长参数:指的是在调用函数时,传入的参数个数可以不固定,而调用函数时,传值的方式无非两种,一种位置实参,另一种时关键字实参,所以对应着,形参也必须有两种解决方案,来分别接收溢出的位置实参(*)与关键字实参(**)

1、形参中某个参数带*形参中的*会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给*后的变量名

 1  def foo(x,y,*z): x=1,y=2,z=(3,4,5,6,7)
 2      print(x)
 3      print(y)
 4      print(z)
 5  foo(1,2,3,4,5,6,7)
 6 
 7  应用
 8  def my_sum(*nums):
 9      res=0
10      for num in nums:
11          res+=num
12      return res
13  print(my_sum(1,2,3,4,5))
View Code

2、实参中的参数也可以带*实参中带*,*会将该参数的值循环取出,打散成位置实参,ps:以后但凡碰到实参中带*的,它就是位置实参,应该立马打散成位置实参去看

 1  def foo(x,y,z):
 2      print(x,y,z)
 3 
 4  foo(1,*[2,3]) foo(1,2,3)
 5  foo(1,*'he') foo(1,'h','e')
 6  foo(1,*(2,3,4)) foo(1,2,3,4)
 7 
 8  def foo(x,y,z,*args):
 9      print(x)
10      print(y)
11      print(z)
12      print(args)
13 
14  foo(1,2,3,4,5,6,7,*[8,9,10,11]) foo(1,2,3,4,5,6,7,8,9,10,11)
15 注意:约定俗成形参中的*变量名的写法都是:*args
View Code

3、形参中某个参数带**--形参中的**会将溢出的关键字实参全部接收,然后存储字典的形式,然后把字典赋值给**后的变量名

1  def foo(x,y,**z): x=1,y=2,z={'c':5,'b':4,'a':3}
2      print(x)
3      print(y)
4      print(z)
5  foo(1,2,a=3,b=4,c=5)
View Code

4、实参中的参数也可以带**,该参数必须是字典--实参中带**,**会将该参数的值循环取出,打散成关键字实参,ps:以后但凡碰到实参中带**的,它就是关键字实参,应该立马打散成关键字实参去看

1  def foo(x,y,z):
2      print(x)
3      print(y)
4      print(z)
5 
6  foo(1,2,**{'a':1,'b':2,'c':3,'z':3}) foo(1,2,c=3,b=2,a=1,z=3)
7  foo(**{'z':3,'x':1,'y':2}) foo(y=2,x=1,z=3)
View Code

注意:约定俗成形参中的**变量名的写法都是:**kwargs

1  def index(name,age,sex):
2      print('welecome %s:%s:%s to index page' %(name,age,sex))
3 
4  def wrapper(*args,**kwargs): args=(1,),kwargs={'x': 1, 'y': 2, 'z': 3}
5      index(*args,**kwargs) index(*(1,),**{'x': 1, 'y': 2, 'z': 3}) index(1,x=1,y=2,z=3)
6 
7  wrapper(name='isetan',sex='male',age=18)
View Code

五 命名关键字形参:在函数定义阶段,*后面的参数都是命名关键字参数(**),特点:在传值时,必须按照key=value的传,并且key必须命名关键字参数指定的参数名

 1 (1 2 def register(x,y,z,**kwargs): kwargs={'b':18,'a':'isetan'}
 3      if 'name' not in kwargs or 'age' not in  kwargs:
 4          print('用户名与年龄必须使用关键字的形式传值')
 5          return
 6      print(kwargs['name'])
 7      print(kwargs['age'])
 8  register(1,2,3,a='isetan',b=18)
 9 (210 def register(x,y,z,*args,name='isetan',age):
11      print(args)
12      print(name)
13      print(age)
14  register(1,2,3,4,5,6,7,age=18)
15 (316 def foo(x,y=1,*args,z=1,a,b,**kwargs):
17      pass
18 
19  foo(1,*[1,2,3],a=1,**{'x':1,'y':2}) foo(1,1,2,3,a=1,y=2,x=1)
20  foo(1,2)
21  foo(x=1,y=2)
View Code

猜你喜欢

转载自www.cnblogs.com/wcl0517/p/9147409.html
今日推荐