xingyemdd

导航

 

一、函数的简介

我们写一个计算字符串或列表等长度的方法,方法类似len()方法,发现实现的代码几乎相同:

1 s1='1234567890'
2 def my_len():
3     count = 0
4     for i in s1:
5         count+=1
6     print(count)
7 my_len()
8 print(len(s1))

首先,之前只要我们执行len方法就可以直接拿到一个字符串的长度了,现在为了实现相同的功能我们把相同的代码写了好多遍 —— 代码冗余

其次,之前我们只写两句话读起来也很简单,一看就知道这两句代码是在计算长度,但是刚刚的代码却不那么容易读懂 —— 可读性差

使用函数可以解决以上问题:

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print(),len()等。但你也可以自己创建函数,这被叫做用户自定义函数。

1、格式

del 关键字 函数名(设定与变量相同):
函数体
return:函数的返回值 
函数名(): 执行函数
函数名会加载到内存,函数体不会执行
():调用运算符

2、return

1)遇到return,结束函数。
2)给函数的调用者(执行者)返回值。
无return 返回None
return 不写或者None 返回None
return 返回单个数
return 返回多个数 将返回的数据放在元组中返回
 1 # 例1
 2 def func1():
 3     print(111)
 4     return
 5     print(222)#此行代码不会执行
 6 func1()
 7 
 8 # 例2
 9 s1='1234567890'
10 def my_len():
11     count = 0
12     for i in s1:
13         count+=1
14     return count
15 print(my_len())
16 
17 #例3
18 s1 = '1234567890'
19 def my_len():
20     count = 0
21     for i in s1:
22         count+=1
23     return count,111,222
24 print(my_len(),type(my_len()))#>>>(10, 111, 222) <class 'tuple'>
25 ret1,ret2,ret3=my_len()#分别赋值
26 print(ret1)#>>>10
27 print(ret2)#>>>111
28 print(ret3)#>>>222
View Code

二、函数的参数

 1 #以下函数实现了len()计算元素长度的功能,但是不能动态的计算
 2 s1 = '1234567890'
 3 def my_len():
 4     count = 0
 5     for i in s1:
 6         count+=1
 7     return count
 8 print(my_len())
 9 print(len(s1))
10 #修改如下,通过函数的参数,可以动态的计算元素的长度
11 s1 = '1234567890'
12 l1=[111,222,3333,'aaaa']
13 def my_len(a):#函数的定义(形参)
14     count = 0
15     for i in a:
16         count+=1
17     return count
18 ret = my_len(s1)#函数的执行(实参)
19 print(ret)#>>>10
20 print(my_len(l1))#>>>4

1、从实参角度

 1 #1.位置参数。必须一一按顺序对应
 2 def func1(x,y):
 3    print(x,y)
 4 func1(1,2)#>>>1 2
 5 
 6 #2.关键字参数。必须一一对应,不分顺序
 7 def func2(x,y,z):
 8     print(x,y,z)
 9 func2(y=2,x=1,z=5)#>>>1 2 5
10 
11 #练习 比较两个数大小
12 def max(x,y):
13     if x>y:
14         return  x
15     else:
16         return y
17 print(max(4,2))#>>>4
18 
19 #三元表达式
20 # def max(a,b):return a if a>b else b
21 
22 #3.混合参数 一一对应 并且关键字参数必须在位置参数后面
23 def func2(argv1,argv2,argv3):
24     print(argv1,argv2,argv3)
25 func2(1,2,argv3=4)#>>>1 2 4

2、从形参角度

 1 #1.位置参数,与实参相同 必须一一对应 按顺序
 2 
 3 #2.默认参数,必须在位置参数后面。
 4 #例:统计人员的姓名和性别,统计在文件当中
 5 def register(name,sex=''):
 6     with open('register',encoding='utf-8',mode='a') as f1:
 7         f1.write('{} {}\n'.format(name,sex))
 8 while True:
 9    name = input('请输入姓名(输入/q 或者 Q 退出):')
10    if name.upper()=='Q':break
11    if 'a' in name:
12        sex = input('请输入性别:')
13        register(name, sex)
14    else:
15        register(name)
16 #3.动态参数 *args, **kwargs 万能参数
17 # 当参数个数不固定时,可以用万能参数
18 def func2(*args,**kwargs):
19      print(args)#元组(接收所有的位置参数,并一起放在元组中)
20      print(kwargs)#字典(接收所有关键字参数,并一起放在字典中)
21 func2(1,2,3,'alex',c='222',v='3333')
22 #顺序:位置参数 *args 默认参数 **kwargs,
23 def func3(a,b,*args,sex='',**kwargs):
24     print(a)
25     print(b)
26     print(sex)
27     print(args)
28     print(kwargs)
29 func3(1,2,'hello','world','你好',sex='',name='Lucy',age=18)
30 #>>>1
31 #>>>2
32 #>>>女
33 #>>>('hello', 'world', '你好')
34 #>>>{'name': 'Lucy', 'age': 18}
35 
36 #传入3个列表,将每一个列表元素添加到args里
37 def func1(*args,**kwargs):#函数的定义:*变量 聚合功能,将所有的实参的位置参数聚合到元组里。**变量 聚合功能,将实参的所有的键值对的参数聚合到字典里。
38     print(args)
39     print(kwargs)
40 l1=[1,2,3,4]
41 l2=['a','b','c',5]
42 l3=(6,7,8,9,0)
43 func1(*l1,*l2,*l3)#函数的执行:*变量 打散功能。
44 #>>>(1, 2, 3, 4, 'a', 'b', 'c', 5, 6, 7, 8, 9, 0)
45 #>>>{}
46 dic1={'name1':'Lucy'}
47 dic2={'name2':'Lily'}
48 func1(**dic1,**dic2)
49 #>>>()
50 #>>>{'name1': 'Lucy', 'name2': 'Lily'}

 三、函数的进阶

python不是内存级别的编程语言,C语言是内存级别的编程语言,有指针的概念。

我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。
  等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;
在函数的运行中开辟的临时的空间叫做局部命名空间。

名称空间:包括全局名称空间,局部名称空间,内置名称空间。

全局名称空间:程序运行时,存放变量与值的关系
临时名称空间:也叫局部名称空间。存入函数里面的变量与值的关系,随着函数的执行结束,临时名称空间消失
内置名称空间:创建py文件后,就会把内置名称空间加载到内存

作用域:全局作用域:包括全局名称空间 、内置名称空间
              局部作用域:局部名称空间
加载顺序:内置名称空间--->全局名称空间--->局部名称空间(函数执行时)
取值顺序:局部名称空间--->全局名称空间--->内置名称空间

 1 #内置函数
 2 #globals() 把全局变量和值的关系放在字典中
 3 #locals() 把局部变量与值的关系放在字典中
 4 name1='Lucy'
 5 def func1():
 6     name2 = 'Lily'
 7     print(globals())
 8     print(locals())
 9 func1()
10 #>>>{'__name__': '__main__', '__doc__': '\n\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001E474CEC2B0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/28163/PycharmProjects/python21期/day3/day3笔记.py', '__cached__': None, 'name1': 'Lucy', 'func1': <function func1 at 0x000001E474DC5F28>}
11 #>>>{'name2': 'Lily'}
12 #关键字 : global    nonlocal

 四、关键字: global    nonlocal

1、global:声明一个全局变量,更改一个全局变量

 1 def func1():
 2     global name#在局部名称空间声明一个全局变量
 3     name='Lucy'
 4     return
 5 func1()
 6 print(name)#>>>Lucy
 7 
 8 name='Lily'
 9 def func1():
10     global name#修改全局变量
11     name='Lucy'
12     return
13 func1()
14 print(name)#>>>Lucy

2、nonlocal:不能对全局变量进行引用,可以对局部作用域的变量进行引用和更改

 1 def func1():
 2     name = 'Lily'
 3     print('1:',name)
 4     def func2():
 5         nonlocal name#修改局部变量
 6         name='Lucy'
 7         print('2:',name)
 8     func2()
 9     print('3:',name)
10 func1()
11 #>>>1: Lily
12 #>>>2: Lucy
13 #>>>3: Lucy

五、函数名

1、第一类对象(first-class object)指
1)可在运行期创建
2)可用作函数参数或返回值
3)可存入变量的实体。

2、函数是第一类对象的概念
1) 函数名 --> 函数的内存地址
2) 函数名可以作为 容器类型的元素 函数的参数、返回值 还能进行赋值 --> 变量

 1 #函数名
 2 # 1、可以互相赋值。
 3 def func1():
 4     print('aaa')
 5 f1=func1
 6 f1()#>>>aaa
 7 
 8 #2、可以当成函数的参数
 9 def func1():
10     print('aaa')
11 def func2(argv):
12     argv()
13     print('bbb')
14 func2(func1)
15 #>>>aaa
16 #>>>bbb
17 
18 #3、可以当成容器类数据类型的参数
19 def func1():
20     print('aaa')
21 def func2():
22     print('bbb')
23 def func3():
24     print('ccc')
25 l1=[func1,func2,func3]
26 for i in l1:
27     i()
28 #>>>aaa
29 #>>>bbb
30 #>>>ccc
31 
32 #4、函数名可以当成函数的返回值
33 def func1():
34     print('aaa')
35 def func2(argv):
36     print('bbb')
37     return argv
38 ret=func2(func1)
39 ret()
40 #>>>bbb
41 #>>>aaa
View Code

 

 

 

posted on 2018-04-19 00:10  xingyemdd  阅读(145)  评论(0编辑  收藏  举报