day6-基础函数的学习(一)

今日份目录python

1.函数的定义linux

2.函数的返回值app

3.函数的参数函数

4.函数的局部变量与全局变量学习

5.名称空间与做用域spa

6.global与nonlocal翻译

7.高阶函数code

 

继续今日份总结!这个总结也晚了,哎,速度仍是太慢!blog

正文开始内存

随着学习进度的逐渐的加深发现咱们的函数体越来重复化愈来愈严重,太多重复代码,这会让咱们的代码的可读性愈来愈差

1.函数的定义

定义:将一组语句集合经过一个名字(函数名)封装起来,只须要执行,调用其函数名

print sayhi ---->返回内存地址

print sayhi()---->返回函数内的内容

特性:

  1. 减小重复代码
  2. 使程序变得可扩展
  3. 使程序变得易维护

哎,跟着金老师开会儿车,虽然我也不懂怎么用,不少人应该都用过探探或者陌陌这类型聊天交友软件,如今写一下大概的软件的搭建

def tantan():
    print('打开手机!')
    print('打开软件!')
    print('附件的人!找到附近的人!')
    print('左滑一下!')
    print('右滑一下!')
    print('锁定目标,联系!')
    print('一块儿大胆约会吧!相约。。。。。')

tantan()#函数的执行者(调用者)
#这大概就是使用探探的整个流程了,每次用都是在调用tantan这个函数,就不须要各类重复代码了!

2.函数的返回值

咱们运行一个函数,函数外部的代码若是须要获取函数内的执行结果,就能够用函数内的return语句把结果返回

return 默认返回这

def tantan():
    print('打开手机!')
    print('打开软件!')
    print('附件的人!找到附近的人!')
    print('左滑一下!')
    print('右滑一下!')
    return
    print('锁定目标,联系!')
    print('一块儿大胆约会吧!')

tantan()
print(666)
#返回值
打开手机!
打开软件!
附件的人!找到附近的人!
左滑一下!
右滑一下!
666

咱们会发现函数在碰到return就会推出函数的运行,跳出函数的运行,return默认值为空

def tantan():
    print('打开手机!')
    print('打开软件!')
    print('附件的人!找到附近的人!')
    print('左滑一下!')
    print('右滑一下!')
    print('锁定目标,联系!')
    print('一块儿大胆约会吧!')
    return ('金刚芭比!')
print(tantan(),type(tantan()))

print(666)
#结果
打开手机!
打开软件!
附件的人!找到附近的人!
左滑一下!
右滑一下!
锁定目标,联系!
一块儿大胆约会吧!
金刚芭比! <class 'str'>
666
def tantan():
    print('打开手机!')
    print('打开软件!')
    print('附件的人!找到附近的人!')
    print('左滑一下!')
    print('右滑一下!')
    print('锁定目标,联系!')
    print('一块儿大胆约会吧!')
    # return ('金刚芭比!')
    return [1,100]
ret = tantan()
print(ret,type(ret))
print(666)
#结果
打开手机!
打开软件!
附件的人!找到附近的人!
左滑一下!
右滑一下!
锁定目标,联系!
一块儿大胆约会吧!
[1, 100] <class 'list'>
666

从上面代码能够看出来,在返回单个值得时候,值是什么类型,返回的就是什么类型

def tantan():
    print('打开手机!')
    print('打开软件!')
    print('附件的人!找到附近的人!')
    print('左滑一下!')
    print('右滑一下!')
    print('锁定目标,联系!')
    print('一块儿大胆约会吧!')
    return ('金刚芭比!','洛天依','初音')

ret = tantan()
print(ret,type(ret))
print(666)
#结果
打开手机!
打开软件!
附件的人!找到附近的人!
左滑一下!
右滑一下!
锁定目标,联系!
一块儿大胆约会吧!
('金刚芭比!', '洛天依', '初音') <class 'tuple'>
666

根据上面三段代码咱们总结出如下几条

  1. 函数在碰到return就会结束函数,并将值返回函数执行者
  2. return默认返回值为空
  3. return返回单个值得时候,值是什么类型,返回值就是什么类型
  4. return返回多个值得时候,会将多个值用逗号分隔,返回一个元祖
  5. 函数返回值永远只能返回一个值

3.函数的参数

def tantan(a,b): #函数定义,形参:形式参数
    print(a,b)
    print('打开手机!')
    print('打开软件!')
    print('附件的人!找到附近的人!')
    print('左滑一下!')
    print('右滑一下!')
    print('锁定目标,联系!')
    print('一块儿大胆约会吧!')
    return ('金刚芭比!','洛天依','初音')
a = 3
b = 2
ret = tantan(a,b)#这个就是函数运行的主体   实参:这个里面的a和b就是实际参数
print(ret,type(ret))
print(666)

3.1 实参:能够是常量、变量、表达式、函数等,不管实参是何种类型的量,在进行函数调用时,它们都必须有肯定的值,以便把这些值传送给形参。所以应预先用赋值,输入等办法使参数得到肯定值.

以一个学生注册的函数来解释实参

def stu_register(name,age,country,course):
    print("----注册学生信息------")
    print("姓名:", name)
    print("age:", age)
    print("国籍:", country)
    print("课程:", course)

stu_register("王山炮",22,"CN","python_devops")
stu_register("张叫春",21,"CN","linux")
stu_register("刘老根",25,"CN","linux")

3.1.1位置参数:按照位置调用顺序,一个一个的调用,传入四个值则则会和下面的调用一一匹配,若是将传入的值调换位置,虽不会报错,显示的内容并不会同样

第一种结果
----注册学生信息------
姓名: 王山炮
age: 22
国籍: CN
课程: python_devops
#调换姓名和年龄
----注册学生信息------
姓名: 22
age: 王山炮
国籍: CN
课程: python_devops

3.1.2关键字参数:既然上面的位置参数更改位置会更改内容,那么就有能够变动位置的参数

stu_register(name="王山炮",age=22,course="python_devops",country="CN")
#结果
----注册学生信息------
姓名: 王山炮
age: 22
国籍: CN
课程: python_devops
发现咱们把参数名称变动位置,函数仍是会识别到传入的参数,放在正确的位置

3.1.3混合参数:就是将位置参数和关键字参数混合的输入

#按照关键字参数放在最前面
stu_register(name="王山炮",22,"python_devops","CN")
执行后报错
SyntaxError: positional argument follows keyword argument
翻译过来的意思就是关键字参数不能放在位置参数前面,应该放在位置参数后面

总结一下就是:

  • 位置参数,从左到右,一一对应
  • 关键字参数,一一对应,不过位置随意
  • 混合参数,不过位置参数必定要在关键字参数前面

3.2 形参

形参:只有被调用时才会分配内存单元,调用结束时,释放分配的内存单元,形参只在函数内部有效,函数调用结束时返回主函数后不能再使用该形参

3.2.1位置参数:总体和实参的位置参数一致,默认一一对应

3.2.2默认参数:若是大量的数据都是默认值,则设定默认参数,若是须要更改在去更改

def stu_register(name,age,course,country='CN'):
    print("----注册学生信息------")
    print("姓名:", name)
    print("age:", age)
    print("国籍:", country)
    print("课程:", course)

stu_register("王山炮",22,"python_devops",)
stu_register("张叫春",21,"linux")
stu_register("刘老根",25,"linux")
#结果
----注册学生信息------
姓名: 王山炮
age: 22
国籍: CN
课程: python_devops
----注册学生信息------
姓名: 张叫春
age: 21
国籍: CN
课程: linux
----注册学生信息------
姓名: 刘老根
age: 25
国籍: CN
课程: linux

不过有个坑默认参数必须放在位置参数后,要否则也会报错

3.2.2.1默认参数的陷阱

#默认参数指向的是一个容器型数据类型,那么这个数据在内存中永远是同一个

def func1(a,l=[]):
    l.append(a)
    return l
print(func1(666))  # [666]
print(func1(22))   # [666,22]
print(func1(33,[]))  # [33]
#结果
[666]
[666, 22]
[33]

3.2.3万能参数:俩个形参接收全部实参传递过来的位置参数以及关键参数

在引入万能参数以前,有如下需求

写一个函数:能够传多个列表,把列表里面的全部元素一个一个的添加到args里面。在不使用万能参数的使用前,咱们估计会一直用for循环分别添加到一个列表而后在打印

def func(*args):  # 在函数的定义时,* 表明聚合。
    print(args)  #(1,2,3,4,5,6,1,2,3)
func(*[1,2,3],*[3,4,5],*[6,7,8])#在函数执行时,*表明打散

#结果
(1, 2, 3, 3, 4, 5, 6, 7, 8)
#换其余试一下
func(*[1,2,3],*(1,2,3),*'fdsaf') # 函数的执行(调用)时,*  打散。
#结果
(1, 2, 3, 1, 2, 3, 'f', 'd', 's', 'a', 'f')
# 动态参数 *args **kwargs
# def func(*args, **kwargs):  # 在函数的定义时,* 表明聚合。
#     print(args)
#     print(kwargs)
# func(1,2,3,4,5,'alex',name='taibai',sex='男')

# * 的魔性用法。
# 在函数的定义时,*  ** 表明聚合。
# 函数的执行(调用)时,* ** 表明打散。

# def func(**kwargs):
#     print(kwargs)
# func(**{"name":'alex'}, **{'age': 46})
def func(*args,**kwargs):
    print(args)
    print(kwargs)
func(*[1,2,3], *'abfc', **{'name':'alex'}, **{'age': 46})
#结果
(1, 2, 3, 'a', 'b', 'f', 'c')
{'name': 'alex', 'age': 46}

关于*的魔性用法在python3.5版本后对于range也开始支持,例子

a,b,*args = [i for i in range(20)]
print(a, b, args)
#结果
0 1 [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

3.2.4 形参的传值顺序

对于形参的传值顺序为(位置参数,*args,默认参数,**kwargs)

def func(a,b,*args,sex='',**kwargs,):
    print(a)
    print(b)
    print(args)
    print(sex)
    print(kwargs)
func(1,2,3,4,5,name='alex')
#结果
1
2
(3, 4, 5)
男
{'name': 'alex'}

若是位置参数与**kwargs变动位置就会发现,**kwargs包含了全部实参的关键字参数,位置参数也被包含进去了。

总结一下

  • 位置参数,从左到右,一一对应
  • 默认参数,放在位置参数后面
  • 万能参数,能接受实参角度全部的位置参数以及关键字参数
  • 形参的顺序,位置参数 *args 关键字参数 **kwargs

4.局部变量与全局变量

函数内外同一个名称的变量,俩个是不同的,看例子

name = '1A'
def change_name():
    name ='2b'  #函数内的name变动为2b,函数外定义的变量仍没有变动,俩者的内存地址不同
    print('',name)
change_name()
print(name)#在函数内部定义的变量称之为局部变量
#结果
里 2b
1A

这样就能够引出全局和局部变量定义

局部变量:在函数结束后,局部变量从内存中清除,俩个函数的局部变量不能互相调用

全局变量:定义在函数外部一级代码的变量,叫全局变量,全局有效

函数内调用变量,优先为局部变量,无则调用全局变量

5.名称空间与做用域

5.1 名称空间

名称空间主要有全局名称空间,局部名称空间,内置名称空间

全局名称空间:存放的是py文件中变量与值的对应关系

局部名称空间:临时存放的是函数体内里面变量与值的对应关系

内置名称空间:内置函数与关键字等等。例如print(), input() break continue

5.2 做用域

全局做用域:内置名称空间,全局名称空间

局部做用域:局部名称空间

加载顺序:加载到内存的顺序

##内置名称空间 ----->全局名称空间 ------>(当函数执行时)局部名称空间

5.3 取值顺序

取值顺序采用就近原则

LEGB原则(局部空间---->父级空间---->全局空间---->内置名称空间)

局部名称空间---->全局名称空间---->内置名称空间

5.4 globals() 与locals()

是俩个python中的内置函数

name = 'alex'
age = 46

def func():
    name1 = 'barry'
    age1 = 18
    def inner():
        print(name1,age1)
        print(globals())  # 返回一个字典:包含全局做用域全部的内容
        print(locals()) # 返回一个字典:当前做用域的全部内容
    inner()
func()
print(globals())  # 返回一个字典:包含全局做用域全部的内容
print(locals())  # 返回一个字典:当前做用域的全部内容

6.global与nonlock的使用

6.1 global : 能够局部声明一个全局变量

age = 46
name = 'xxx'
def func():
    global name
    name = 'alex'
    name = 'barry'
func()
name = 'qqq'
print(name)

# 局部做用域不能对全局做用域的变量进行修改,只能引用。
count = 1
def func():
    global count
    count += 1
func()
print(count)

总结:global :

  • 能够局部做用域声明一个全局变量
  • 局部做用域不能对全局做用域的变量进行修改,只能引用,经过设置global能够修改。

6.2 nonlock

# nonlocal : 只在python3x中 存在。
# 1,不能操控全局变量。
# name = 'alex'
# def func():
#     nonlocal name
#     print(name)
# func()

# 内层函数不能对外层函数的变量进行修改,只能引用。
# 在局部做用域中,对父级做用域(或者更外层做用域非全局做用域)的变量进行引用和修改,
# 而且引用的哪层,从那层及如下此变量所有发生改变。
def wrapper():
    name = 'alex'
    def inner():
        nonlocal name
        name += 'b'
        # print(name)
    print('1', name)
    inner()
    print('2', name)
wrapper()

7.嵌套函数与高阶函数

7.1嵌套函数

  • 函数内部能够再次定义函数,执行须要被调用
  • 同名字的变量会一层一层的向上查找变量
  • 注意执行顺序以及变量内外

7.2 高阶函数

定义:变量能够指向函数,函数的参数能接收变量,那么一个函数就能够接收另外一个函数做为参数,这种函数被称之为高阶函数

  • 接收一个或者多个函数做为参数
  • return返回另一个函数

 

 

要抓紧速度了,速度太慢了,加油!