python全栈开发—函数整理(最后一次整理,不能再全了)

函数

函数介绍
函数定义
函数的调用
函数的返回值
    总结
函数的参数
    参数
    参数的分类
        位置参数
        关键字参数
        混合参数
        总结
        动态接收位置参数
        动态接收关键字参数
函数的注释
名称空间
函数的嵌套
gloabal、nonlocal
    global 宗旨
    nonlocal宗旨
内置函数
    作用域相关
        locals()
        globals()
    迭代器相关
        range()
        next()
        iter()
    字符串类型代码的执行
        eval()
        exec()
    输入和输出相关
        input()
        print()
    内存相关
        hash()
        id()
    文件操作相关
        open()
    帮助
        help()
    调用相关
        callable()
    查看内置属性
        dir()
    基础数据类型相关
        数字相关
        数学运算
        数据结构相关
    数据集合
    其他相关
    lambda
    sorted
    filter
    map
    reduce

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

函数介绍

我们目前为止,已经可以完成一些软件的基本功能了,那么我们来完成这样一个功能:约x

我们先要约会,首先应该把手机拿出来打开聊天软件,然后问她约不约,等等….

用之前的学到知识怎么实现这个过程

pint("拿出手机")
print("打开陌陌")
print("找个漂亮的妹子")
print("问她,约不约啊!")
print("ok 走起")

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

ok so easy我们已经完成了对一个功能的描述,那么问题来了,我还想在约一次怎么搞,是不是就是在写一遍

# 约一次
pint("拿出手机")
print("打开陌陌")
print("找个漂亮的妹子")
print("问她,约不约啊!")
print("ok 走起")
# 再约一次
pint("拿出手机")
print("打开陌陌")
print("找个漂亮的妹子")
print("问她,约不约啊!")
print("ok 走起")

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

ok 非常简单搞定了,但是我还想约上个10次8次的,怎么搞,加个循环不就行了吗?

while True:
    pint("拿出手机")
    print("打开陌陌")
    print("找个漂亮的妹子")
    print("问她,约不约啊!")
    print("ok 走起")

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这样看似实现了但是也不能一直约吧,人还是要有节制的,约完了总是不放心,去医院看看吧.没问题就继续约

也就是想什么时候约就什么时候约,这可怎么实现啊??有点难住我胡汉三了.

好了说到这 我们就这样做,把约这个事,先计划好,然后按照安排好的流程.在需要约的时候 把这个约的流程拿出来执行以下就好了.

def yue():
    print('拿出手机')
    print('打开陌陌')
    print('找个漂亮妹子')
    print('问她约不约')
    print('ok,走起')

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

那么这里.我们可以先去定义一个事情或者是功能,等到需要的时候直接去用就好了.

聪明的你也猜到了这就是函数,是的它就是函数.那这个东西怎么用啊??
函数定义

def 是python中关键字主要用来定义函数的

yue这个是函数的名字

()这个括号是个神奇的东西,咱们后边会详细盘它
冒号是表示咱们这个语句写完了

细心的人看到怎么print都在里边,是的怎么要有一个缩进 缩进就是4个空格 缩进的意思里边的代码都是函数下边的代码

我们现在就来实现刚刚我们说的定义一个约x功能:

def yue():
    print("拿出手机")
    print("打开陌陌")
    print("找一个漂亮的妹子")
    print("问她,约不约啊")
    print("ok 走起")

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
哦了,这就定义完了,但是这个时候我们去执行,会发生什么现象? 什么都没有发生.因为我只定义了一个函数.但是还没有执行过这个函数.
函数的调用

使用函数名加小括号就可以调用了 写法:函数名() 这个时候函数的函数体会被执行

# 调用yue函数
def yue():
    print("拿出手机")
    print("打开陌陌")
    print("找一个漂亮的妹子")
    print("问 约不约啊")
    print("ok 走起")
yue()   # 这是yue函数的调用

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述
现在就实现了约一次,我想要约几次我就只需要

yue()
yue()
yue()
yue()
yue()
yue()

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
直接调用定义好的函数就可以了
函数的返回值

咱们约完之后的得有个结果吧, 比如是约的萝莉,还是大妈啊总得有个结果,那么这个结果

怎么来描述和获得呢? 这就涉及到函数的返回值啦

执行完函数之后,我们可以使用return来返回结果

def yue():
    print("约你")
    print("约我")
    print("约他")
    return   
    print("约谁呀")    # 这句话不会被执行
yue()

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

函数中遇到return,此函数结束.不在继续执行

我们现在有return返回值,我们试试返回个东西

def yue():
    print("约你")
    print("约我")
    print("约他")
    return  "美女一枚"
yue()

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们现在返回了一个字符串,但是返回给谁了呢? 这个返回值返回给函数的调用者了,我们来看一下

def yue():
    print("约你")
    print("约我")
    print("约他")
    return '美女一枚'
girl =  yue()
print(girl)
结果:
约你
约我
约他
美女一枚

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

肯定好多朋友还是不明白上边怎么就打印美女一枚了,莫慌看下图:
在这里插入图片描述
定义了一个函数yue
调用函数
执行函数里的约你
执行函数里的约我
执行函数里的约他
返回给调用者一个字符串,这个调用者就是yue()
将返回的字符串通过一个等号赋值给白变量girl
打印变量girl的值

函数的返回值可以有多个结果:

def yue():   
    print("约你")   
    print("约我")   
    print("约他")   
    return "美女一枚", "萝莉一枚"
girl = yue()
print(type(girl))   # tuple

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

总结

1.遇到return,此函数结束,return后面的东西将不会在执行

2.return 返回值

关于返回值:

如果return什么都不写或者干脆就没写return,返回的结果就是None

如果return后面写了一个值,返回给调用者这个值

如果return后面写了多个结果,返回给调用者一个tuple(元祖),调用者可以直接使用解构获取多个变量

OK,完美 可以得到结果了 但是我们约的方式是不是有点问题啊?陌陌现在还能约到吗?约不到了 我们换探探 那要是过几天探探也不行了

是不是会有一个替代品,那你们想有一个替代的,你就需要去改代码.是不是有点不合适了 最好的方式是想用什么约就用什么约 ok 我们也是可以实现的 ,我们就要在函数后边的括号里搞点事情了.
函数的参数

参数,也就是函数括号里的内容 函数在调用的时候指定一个具体的变量的值 就是参数.写法如下:

def 函数名(参数):
    函数体

     
     
  • 1
  • 2

我们应该把代码改一下,能够实现我刚说的那种效果

def yue(chat):
    print("拿出⼿手机")
    print("打开"+chat)
    print("找个漂亮的妹⼦子")
    print("约不不约")
yue("陌陌")
yue("微信")
yue("探探")
结果:
拿出手机
打开陌陌
找个漂亮的妹⼦
约不约
拿出⼿机
打开微信
找个漂亮的妹⼦
约不约
拿出手机
打开探探
找个漂亮的妹⼦
约不约 
搞定了. 我们在调用yue的时候给chat一个值. 然后再执行函数体.

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

参数

1.形参

写在函数声明的位置的变量叫形参,形式上的一个完整.表示这个函数需要xxx

2.实参

在函数调用的时候给函数传递的值.加实参,实际执行的时候给函数传递的信息.表示给函数xxx

3.传参

给函数传递信息的时候将实际参数交给形式参数的过程被称为传参.

def yue(chat):    # chat  形参
    print("拿出手机")
    print("打开"+chat)
    print("找个漂亮的妹子")
    print("约不约")
yue("陌陌")     # 实参
len("字符串")    # "字符串"在这里就是实参
print("麻花藤")    # "麻花藤"就是实参

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

参数的分类
位置参数

约到现在,有没有想过这么一个问题,啥样的约么? 哪里的都约么? 不一定吧.比如我现在在北京,我很寂寞,我喜欢小姐姐

alex 在泰国,很寂寞 人妖就行了 .需求是不一样的 而我们现在的函数没有这些功能 那怎么办呢? 很简单 多来几个参数就好了

def yue(chat,addr,age):    # chat  形参
    print("拿出手机")
    print("打开"+chat)
    print("找个" + addr +"附近漂亮的" + str(age) + "岁妹子")
    print("约不约")
yue("陌陌","北京",18)    # 实参
结果:
拿出手机
打开陌陌
找个北京附近漂亮的18岁妹子
约不约

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上述代码分析: 在访问yue()的时候,我们按照位置的顺序分别把”陌陌”,”北京”,18赋值给了chat,addr,age,在传参过程中.系统会按照位置把实参赋值到形参.

形参就是一个变量名,实参就是值 传参就是在赋值
练习

编写函数,给函数传递两个参数a,b a,b相加 返回a参数和b参数相加的和

def f(a,b):
    c = a+b
    return c
num_sum = f(5,8)
print(num_sum)
结果: 13

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

编写函数,给函数传递两个参数a,b 比较a,b的大小 返回a,b中最大的那个数

def f(a,b):
    if a>b:
        return a
    else:
        return b
num_sum = f(5,8)
print(num_sum)
结果:8

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

比较大小的这个写法有点麻烦,我们在这里学一个三元运算符

def f(a,b):
    c = a if a > b else b  #当a>b就把a赋值给c,否则就把b赋值给c
    return c
msg = f(5,7)
print(msg)
结果:
7

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

关键字参数

位置参数好不好呢? 如果是少量的参数还算OK, 没有问题. 但是如果函数在定义的时候参数非常多怎么办? 程序员必须记住, 我有哪些参数, 而且还有记住每个参数的位置, 否则函数就不能正常调用了. 那则么办呢? python提出了一种叫做关键字参数. 我们不需要记住每个参数的位置. 只要记住每个参数的名字就可以了

def yue(chat, address, age):
    print("拿出手机")
    print("打开"+chat)
    print("找个"+address+"附近漂亮的"+str(age)+"岁妹子")
    print("约不约")
yue(chat="微信", age=18, address="北京")       # 关键字参数.
结果:
拿出手机
打开微信
找个北京附近漂亮的18岁妹子
约不约

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

搞定, 这样就不需要记住繁琐的参数位置了.
混合参数

可以把上面两种参数混合着使用. 也就是说在调用函数的时候即可以给出位置参数, 也可以指定关键字参数.

# 混合参数 
yue("微信", age=18, address="上海")    # 正确.第一个位置赋值给chat, 后面的参数开始指定关键字.
yue(age="18", "微信", address="广州")  # 错误, 最开始使用了关键字参数, 那么后面的 微信的位置就串了, 容易出现混乱

     
     
  • 1
  • 2
  • 3

注意: 在使用混合参数的时候, 关键字参数必须在位置参数后面
总结

综上: 在实参的⾓角度来看. 分为三种:

位置参数
关键字参数
混合参数, 位置参数必须在关键字参数前面

     
     
  • 1
  • 2
  • 3

位置参数:

位置参数,按照位置来赋值,到目前为止,我们编写的函数都是这种

def yue(chat, address, age):
    print("拿出手机")
    print("打开"+chat)
    print("找个"+address+"附近漂亮的"+str(age)+"岁妹子")
    print("约不约")

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

默认值参数:

在函数声明的时候, 就可以给出函数参数的默认值. 在调用的时候可以 给出具体的值, 也可以不给值, 使⽤用默认值. 比如, 我们录入咱们班学生的基本信息. 通过调查发现. 我们班大部分学生都是男生. 这个时 候就可以给出⼀一个sex=’男’的默认值.

def stu_info(name, age, sex='男'):
    print("录入学生信息")
    print(name, age, sex)
    print("录入完毕")
stu_info("张强", 18)

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

注意:必须先声明在位置参数,才能声明关键字参数

综上:在形参的角度来看

位置参数
默认值参数(大多数传进来的参数都是一样的, 一般用默认参数

     
     
  • 1
  • 2

函数参数-动态参数

形参的第三种:动态参数

首先我们来回顾下位置参数

def eat(a,b,c):
    print('我想吃%s%s%s'%(a,b,c))
eat('大米饭','中米饭','小米饭')

     
     
  • 1
  • 2
  • 3

现在有个问题,你们看我这体型也知道吃的不止这些,数量也没有写,这时我们就要用到动态参数
动态接收位置参数

在参数位置用*表示接受任意参数

def eat(*args):
    print('我想吃',args)
eat('大米饭','中米饭','小米饭')  # 收到的结果是一个tuple元祖

     
     
  • 1
  • 2
  • 3

动态接收参数的时候要注意: 动态参数必须在位置参数后面

def eat(*args,a,b):
    print('我想吃',args,a,b)
eat('大米饭','中米饭','小米饭')
结果:
TypeError: eat() missing 2 required keyword-only arguments: 'a' and 'b'
# eat函数在调用的时候发现缺少俩个位置参数没有进行传递

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通过上述代码发现一个问题就是,我们明明给了多个参数,为什么还会提示参数未传递呢?

原因就是因为这个在搞鬼 把所有的位置参数都给接受了,所有会报错.我们尝试着把a,b放在的前面试试

def eat(a,b,*args):
    print('我想吃',args,a,b)
eat('大米饭','中米饭','小米饭')
结果:
我想吃 ('小米饭',) 大米饭 中米饭

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

动态接收参数的时候要注意:动态参数必须在位置参数后面

那默认值参数呢?

def eat(a,b,c='白菜',*args):
    print('我想吃',a,b,c,args)
eat('豆腐','粉条','猪肉','大葱')
结果:
我想吃 豆腐 粉条 猪肉 ('大葱',)  # 我们定义好的白菜没有生效,被猪肉给覆盖了

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

我们发现默认值参数写在动态参数前面,默认值的参数是不会生效的

def eat(a,b,*args,c='白菜'):
    print('我想吃',a,b,args,c)
eat('猪肉','粉条','豆腐','大葱')
结果:
我想吃 猪肉 粉条 ('豆腐', '大葱') 白菜  # 这样默认参数就生效了

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

这个时候如果你不给出关键字传参,那么你的默认值是永远都生效的

注意: 形参的顺序: 位置参数 , 动态参数 , 默认参数
动态接收关键字参数

在python中可以动态的位置参数,但是这种情况只能接收位置参数无法接收关键字参数,在python中使用*来接收动态关键字参数

def func(**kwargs):
    print(kwargs)     
func(a=1, b=2, c=3)
结果:
{'a': 1, 'b': 2, 'c': 3}

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

动态关键字参数最后获取的是一个dict字典形式

顺序的问题, 在函数调用的时候, 如果先给出关键字参数, 则整个参数列表会报错.

def func(a,b,c,d):
    print(a,b,c,d)
func(1,2,c=3,4)
结果:
  File "D:/python_object/path2/test.py", line 806
    func(1,2,c=3,4)              ^
SyntaxError: positional argument follows keyword argument

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

关键参数必须要放在位置参数后边,由于实参是这个顺序,所以形参接收的时候也是这个顺序.也就是说位置参数必须在关键字参数前面.动态接收关键字参数也要在后面

最终顺序:

位置参数 > args(动态位置参数) > 默认值参数 > *kwargs(动态默认参数)

这四种参数可以任意的使用

如果想接收所有的参数:

def func(*args,**kwargs):
    print(args,kwargs)
func(1,23,5,a=1,b=6)

     
     
  • 1
  • 2
  • 3

动态参数还可以这样传参:

lst = [1,4,7]
# 方法一
def func(*args):
    print(args)
func(lst[0],lst[1],lst[2])
# 方法二
def func(*args):
    print(args)
func(*lst)  
# 在实参的位置上用*将lst(可迭代对象)按照顺序打散
# 在形参的位置上用*把收到的参数组合成一个元祖

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

字典也可以进行打散,不过需要**

dic = {'a':1,'b':2}
def func(**kwargs):
    print(kwargs)
func(**dic)

     
     
  • 1
  • 2
  • 3
  • 4

函数的注释

def eat(food,drink):
    '''
    这里描述这个函数是做什么的.例如这函数eat就是吃
    :param food:  food这个参数是什么意思
    :param drink: drink这个参数是什么意思
    :return:  执行完这个函数想要返回给调用者什么东西
    '''
    print(food,drink)
eat('麻辣烫','肯德基')

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在外部查看函数的注释 函数名.doc

print(eat.__doc__)  #函数名.__doc__
结果:
    这里描述这个函数是做什么的.例如这函数eat就是吃
    :param food:  food这个参数是什么意思
    :param drink: drink这个参数是什么意思
    :return:  执行完这个函数想要返回给调用者什么东西

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

名称空间

在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了, 至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始的时候函数只是加载进来, 仅此而已, 只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空间也会随着函数执行完毕而被清空.

def fun():   
    a = 10   
    print(a)
fun()
print(a)    # a不存在了已经..

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

​ 我们给存放名字和值的关系的空间起一个名字叫: 命名空间. 我们的变量在存储的时候就 是存储在这片空间中的.

​ 命名空间分类:

​ 1. 全局命名空间—> 我们直接在py文件中, 函数外声明的变量都属于全局命名空间

​ 2. 局部命名空间—> 在函数中声明的变量会放在局部命名空间

​ 3. 内置命名空间—> 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间

加载顺序:

内置命名空间
全局命名空间

     
     
  • 1
  • 2

​ 3. 局部命名空间(函数被执行的时候)

取值顺序:

​ 1. 局部命名空间

​ 2. 全局命名空间

​ 3. 内置命名空间

a = 10
def func():  
    a = 20   
    print(a)
func()  # 20

     
     
  • 1
  • 2
  • 3
  • 4
  • 5

作用域: 作用域就是作用范围, 按照生效范围来看分为 全局作用域 和 局部作用域

全局作用域: 包含内置命名空间和全局命名空间. 在整个文件的任何位置都可以使用(遵循 从上到下逐⾏执行).

局部作用域: 在函数内部可以使用.

作⽤域命名空间:

全局作⽤用域: 全局命名空间 + 内置命名空间
局部作⽤用域: 局部命名空间 

     
     
  • 1
  • 2

我们可以通过globals()函数来查看全局作⽤用域中的内容,也可以通过locals()来查看局部作 ⽤用域中的变量量和函数信息

a = 10
def func():   
    a = 40   
    b = 20   
    print("哈哈")   
    print(a, b)        
    print(globals())    # 打印全局作用域中的内容   
    print(locals())     # 打印局部作用域中的内容
func()

     
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
函数的嵌套

只要遇见了()就是函数的调用. 如果没有()就不是函数的调用
函数的执行顺序

def fun1():
print(111)
def fun2():
print(222)
fun1()
fun2()
print(111)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

def fun2():   
    print(222)   
    def fun3():       
        print(666)   
    print(444)   
    fun3()   
    print(888)
print(33)
fun2()
print(555)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述
gloabal、nonlocal

首先我们写这样一个代码, 首先在全局声明一个变量, 然后再局部调用这个变量, 并改变这 个变量的值

a = 100
def func():   
    global a    # 加了个global表示不再局部创建这个变量了. 而是直接使用全局的a   
    a = 28   
print(a)
func()
print(a)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

global表示. 不再使用局部作用域中的内容了. 而改用全局作用域中的变量
global 宗旨

在函数内部修改全局的变量,如果全局中不存在就创建一个变量

lst = ["麻花藤", "刘嘉玲", "詹姆斯"]
def func():   
    lst.append("⻢云")   
    # 对于可变数据类型可以直接进⾏访问
   print(lst)
func()
print(lst)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

nonlocal宗旨

nonlocal 只修改上一层变量,如果上一层中没有变量就往上找一层,只会找到函数的最外层,不会找到全局进行修改

a = 10
def func1():   
    a = 20   
    def func2():
        nonlocal a       
        a = 30       
        print(a)  
    func2()   
    print(a)
func1()
结果:
加了nonlocal
30
30
不加nonlocal
30
20

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

再看, 如果嵌套了很多层, 会是一种什么效果:

a = 1
def fun_1():   
    a = 2   
    def fun_2():       
        nonlocal a       
        a = 3       
        def fun_3():           
            a = 4           
            print(a)       
        print(a)       
        fun_3()       
        print(a)   
    print(a)   
    fun_2()   
    print(a)
print(a)
fun_1()
print(a)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这样的程序如果能分析明白. 那么作用域, global, nonlocal就没问题了
内置函数

什么是内置函数? 就是python给你提供的. 拿来直接用的函数, 比如print., input等等.

截止 到python版本3.6.2 python一共提供了68个内置函数. 有 一些我们已经用过了. 有一些还没有用过. 还有一些需要学完了面向对象才能继续学习的.

今 天我们就认识一下python的内置函数.

在这里插入图片描述
作用域相关
locals()

返回当前作⽤用域中的名字
globals()

返回全局作⽤用域中的名字
迭代器相关
range()
next()

迭代器向下执⾏一次, 内部实际使用了next()方法返回迭代器的下一个项目
iter()

获取迭代器, 内部实际使用的是iter()方法来获取迭代器
字符串类型代码的执行
eval()

执行部分字符串类型的代码,并返回最终结果

print(eval("2+2"))
# 4
n = 8
print(eval("2+n"))
# 10
def func():
    print(666)
eval("func()")
# 666

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

exec()

执行字符串类型的代码

msg = '''
def func():
    print('有计划没行动等于零')
func()
'''
exec(msg)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

以上这两个在公司开发中禁止使用,如果里边出现del就会出现很大的问题
输入和输出相关
input()

获取用户输入的内容
print()

打印输出

print('你好','我好')    
print('你好','我好',sep='|')
结果:
你好 我好
你好|我好

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

sep是将多个元素进行修改 默认的是空格

print('你好')
print('我好')
print('你好',end='')
print('我好')

  
  
  • 1
  • 2
  • 3
  • 4

end默认是\n 这就是我们为什么使用print的时候会出现换行,end的值修改成了空字符串
内存相关
hash()

获取到对象的哈希值(int, str, bool, tuple)

print(hash('123'))
结果:
-6822401661081700707

  
  
  • 1
  • 2
  • 3

这样是求出数据结构,如果能够获取到哈希值就是可以当做字典的键
id()

获取到对象的内存地址
文件操作相关
open()

用于打开一个文件, 创建一个文件句柄
帮助
help()

函数用于查看函数或模块用途的详细说明

help(print)
结果:
Help on built-in function print in module builtins:
print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.
Process finished with exit code 0

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

调用相关
callable()

用于检查一个对象是否是可调用的. 如果返回True, object有可能调用失败, 但如果返回False. 那调用绝对不会成功

print(callable(print))
结果:
True

  
  
  • 1
  • 2
  • 3

查看内置属性
dir()

查看对象的内置属性

方法.访问的是对象中的dir()⽅方法

print(dir(list))
结果:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

  
  
  • 1
  • 2
  • 3

基础数据类型相关
数字相关

​ bool() 将给定的数据转换成bool值. 如果不给值. 返回False
​ int() 将给定的数据转换成int值. 如果不给值, 返回0
​ float() 将给定的数据转换成float值. 也就是小数
​ complex() 创建一个复数. 第一个参数为实部, 第二个参数为虚部. 或者第一个参数直接 用字符串来描述复数
数学运算

​ abs() 返回绝对值

print(abs(-1))
结果:
1

  
  
  • 1
  • 2
  • 3

​ divmod() 返回商和余数

print(divmod(15,2))
结果:
(7, 1)

  
  
  • 1
  • 2
  • 3

​ round() 四舍五入

print(round(15.1111,2))  # 保留2位小数
结果:
15.11

  
  
  • 1
  • 2
  • 3

​ pow(a, b) 求a的b次幂, 如果有三个参数. 则求完次幂后对第三个数取余

print(pow(15,2,3))
结果:
0

  
  
  • 1
  • 2
  • 3

​ sum() 求和

print(sum([12,3,4]))  #sum里边的参数是一个可迭代对象
结果:
19

  
  
  • 1
  • 2
  • 3

​ min() 求最小值

print(min([12,3,4]))  # 寻找最小的数字
结果:
3

  
  
  • 1
  • 2
  • 3

​ max() 求最大值

print(max([12,3,4]))  # 寻找最大的数字
结果:
12

  
  
  • 1
  • 2
  • 3

数据结构相关

​ 列表和元组:
​ list() 将一个可迭代对象转换成列表
​ tuple() 将一个可迭代对象转换成元组
​ reversed() 将一个序列翻转, 返回翻转序列的迭代器

reversed 示例:

l = reversed('你好')  # l 获取到的是一个生成器
print(list(l))

  
  
  • 1
  • 2

字符串相关:
str() 将数据转化成字符串
format() 与具体数据相关, 用于计算各种小数, 精算等

print(format('meet','>20'))   # 右对齐
print(format('meet','<20'))   # 左对齐
print(format('meet','^20'))   # 居中

  
  
  • 1
  • 2
  • 3

数值

#数值
print(format(3,'b'))    # 二进制
print(format(97,'c'))   # 转换成unicodezif
print(format(11,'d'))   #十进制
print(format(56))     #和d一样
print(format(11,'n'))   #十进制
print(format(11,'o'))   #八进制
print(format(11,'x'))  # 十六进制(小写字母)
print(format(11,'X'))  # 十六进制(大写字母)
# 浮点数
print(format(1234567890,'e'))  #科学计算法,默认使用6位
print(format(123456789,'0.2e'))# 科学计算,保留2位小数(小写)
print(format(123456789,'0.2E'))# 科学计算,保留2位小数(大写)
print(format(1.23456789,'f')) #小数点计数法,保留6位小数
print(format(1.23456789,'0.2f')) # 小数点计数法,保留2位数
print(format(1.23456789,'0.10f')) # 小数点计数法,保留2位数
print(format(1.23456789e+1000,'F')) # 小数点计数法

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

bytes() 把字符串转换成bytes类型

s = '你好武大'
bs = s.encode('utf-8')
print(bs)
结果:b'\xe4\xbd\xa0\xe5\xa5\xbd\xe6\xad\xa6\xe5\xa4\xa7'
s1 = bs.decode('utf-8')
print(s1)
结果: 你好武大
s = '你好'
bs = bytes(s,encoding='utf-8')
print(bs)
# 将字符串转换成字节
bs1 = str(bs,encoding='utf-8')
print(bs1)
# 将字节转换成字符串

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

repr() 返回一个对象的官方表示形式

# repr 输出一个字符串的官方表示形式. 
print(repr('大家好,\n \t我叫周杰伦')) print('大家好我叫周杰伦') 
# %r  
%r用的就是repr 
name = 'taibai' 
print('我叫%r' % name)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

数据集合

dict() 创建一个字典

set() 创建一个集合

frozenset() 创建一个冻结的集合,冻结的集合不能进行添加和删除操作
其他相关

len() 返回一个对象的元素个数

enumerate() 获取枚举对象

enumerate() 举例

lst = ['alex','wusir','taibai']
for i,k in enumerate(lst):
    print('这是序号',i)
    print('这是元素',k)

  
  
  • 1
  • 2
  • 3
  • 4

all() 可迭代对象中全部是True,结果才是True

lst = [1,2,3,4,True,0,False]
lst1 = [1,2,3,4,True]
print(all(lst))
print(all(lst1))
结果:
False
True

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

any() 可迭代对象中有一个是True,就是True

lst = [1,2,3,4,True,0,False]
lst1 = [1,2,3,4,True]
print(any(lst))
print(any(lst1))
结果:
False
True

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元祖,

然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回

lst1 = [1,2,3]
lst2 = ['a','b','c','d']
lst3 = (11,12,13,14,15)
for i in zip(lst1,lst2,lst3):
    print(i)
结果:
(1, 'a', 11)
(2, 'b', 12)
(3, 'c', 13)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

lambda

匿名函数,为了解决一些简单的需求而设计的一句话函数

def func(n):
    return n**n
print(func(4))
f = lambda x: x**x
print(f(4))
结果:
256
256

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

lambda表示的是匿名函数,不需要用def来声明,一句话就可以声明出一个函数

语法:

函数名 = lambda 参数:返回值

注意:

1.函数的参数可以有多个,多个参数之间用逗号隔开

2.匿名函数不管多复杂.只能写一行.且逻辑结束后直接返回数据

3.返回值和正常的函数一样,可以是任意数据类型,返回值的时候只能返回一个不能返回多个

匿名函数并不是说一定没有名字,这里前面的变量就是一个函数名,说他是匿名原因是我们通过

name查看的时候是没有名字的.统一都叫做lambda.在调用的时候没有什么特别之处

像正常的函数调用既可
sorted

排序函数

语法:sorted(iterable,key=None,reverse=False)

iterable : 可迭代对象

key: 排序规则(排序函数),在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数.根据函数运算的结果进行排序

reverse :是否是倒叙,True 倒叙 False 正序

lst = [1,3,2,5,4]
lst2 = sorted(lst)
print(lst)    #原列表不会改变
print(lst2)   #返回的新列表是经过排序的
lst3 = sorted(lst,reverse=True)
print(lst3)   #倒叙
结果:
[1, 3, 2, 5, 4]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

字典使用sorted排序

dic = {1:'a',3:'c',2:'b'}
print(sorted(dic))   # 字典排序返回的就是排序后的key
结果:
[1,2,3]

  
  
  • 1
  • 2
  • 3
  • 4

和函数组合使用

# 定义一个列表,然后根据一元素的长度排序
lst = ['天龙八部','西游记','红楼梦','三国演义']
# 计算字符串的长度
def func(s):
    return len(s)
print(sorted(lst,key=func))
# 结果:
# ['西游记', '红楼梦', '天龙八部', '三国演义']

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

和lambda组合使用

lst = ['天龙八部','西游记','红楼梦','三国演义']
print(sorted(lst,key=lambda s:len(s)))
结果:
['西游记', '红楼梦', '天龙八部', '三国演义']
lst = [{'id':1,'name':'alex','age':18},
    {'id':2,'name':'wusir','age':17},
    {'id':3,'name':'taibai','age':16},]
# 按照年龄对学生信息进行排序
print(sorted(lst,key=lambda e:e['age']))
结果:
[{'id': 3, 'name': 'taibai', 'age': 16}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'alex', 'age': 18}]

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

filter

筛选过滤

语法: filter(function,iterable)

function: 用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留此项数据

iterable:可迭代对象

lst = [{'id':1,'name':'alex','age':18},
        {'id':1,'name':'wusir','age':17},
        {'id':1,'name':'taibai','age':16},]
ls = filter(lambda e:e['age'] > 16,lst)
print(list(ls))
结果:
[{'id': 1, 'name': 'alex', 'age': 18},
 {'id': 1, 'name': 'wusir', 'age': 17}]

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

map

映射函数

语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取执行function

计算列表中每个元素的平方,返回新列表

lst = [1,2,3,4,5]
def func(s):
    return  s*s
mp = map(func,lst)
print(mp)
print(list(mp))

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

改写成lambda

lst = [1,2,3,4,5]
print(list(map(lambda s:s*s,lst)))

  
  
  • 1
  • 2

计算两个列表中相同位置的数据的和

lst1 = [1, 2, 3, 4, 5]
lst2 = [2, 4, 6, 8, 10]
print(list(map(lambda x, y: x+y, lst1, lst2)))
结果:
[3, 6, 9, 12, 15]

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

reduce

from functools import reduce
def func(x,y):
    return x + y
# reduce 的使用方式:
# reduce(函数名,可迭代对象)  # 这两个参数必须都要有,缺一个不行
ret = reduce(func,[3,4,5,6,7])
print(ret)  # 结果 25
reduce的作用是先把列表中的前俩个元素取出计算出一个值然后临时保存着,
接下来用这个临时保存的值和列表中第三个元素进行计算,求出一个新的值将最开始
临时保存的值覆盖掉,然后在用这个新的临时值和列表中第四个元素计算.依次类推
注意:我们放进去的可迭代对象没有更改
以上这个例子我们使用sum就可以完全的实现了.我现在有[1,2,3,4]想让列表中的数变成1234,就要用到reduce了.
普通函数版
from functools import reduce
def func(x,y):
    return x * 10 + y
    # 第一次的时候 x是1 y是2  x乘以10就是10,然后加上y也就是2最终结果是12然后临时存储起来了
    # 第二次的时候x是临时存储的值12 x乘以10就是 120 然后加上y也就是3最终结果是123临时存储起来了
    # 第三次的时候x是临时存储的值123 x乘以10就是 1230 然后加上y也就是4最终结果是1234然后返回了
l = reduce(func,[1,2,3,4])
print(l)
匿名函数版
l = reduce(lambda x,y:x*10+y,[1,2,3,4])
print(l)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在Python2.x版本中recude是直接 import就可以的, Python3.x版本中需要从functools这个包中导入

龟叔本打算将 lambda 和 reduce 都从全局名字空间都移除, 舆论说龟叔不喜欢lambda 和 reduce

最后lambda没删除是因为和一个人写信写了好多封,进行交流然后把lambda保住了.

参考资料:

https://www.processon.com/view/link/5b4ee15be4b0edb750de96ac

                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-b6c3c6d139.css" rel="stylesheet">
                                            <div class="more-toolbox">
            <div class="left-toolbox">
                <ul class="toolbox-list">
                    
                    <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#csdnc-thumbsup"></use>
                    </svg><span class="name">点赞</span>
                    <span class="count"></span>
                    </a></li>
                    <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#icon-csdnc-Collection-G"></use>
                    </svg><span class="name">收藏</span></a></li>
                    <li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;1582594662_002&quot;}"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#icon-csdnc-fenxiang"></use>
                    </svg>分享</a></li>
                    <!--打赏开始-->
                                            <!--打赏结束-->
                                            <li class="tool-item tool-more">
                        <a>
                        <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                        </a>
                        <ul class="more-box">
                            <li class="item"><a class="article-report">文章举报</a></li>
                        </ul>
                    </li>
                                        </ul>
            </div>
                        </div>
        <div class="person-messagebox">
            <div class="left-message"><a href="https://blog.csdn.net/xie_qi_chao">
                <img src="https://profile.csdnimg.cn/B/F/6/3_xie_qi_chao" class="avatar_pic" username="xie_qi_chao">
                                        <img src="https://g.csdnimg.cn/static/user-reg-year/1x/2.png" class="user-years">
                                </a></div>
            <div class="middle-message">
                                    <div class="title"><span class="tit"><a href="https://blog.csdn.net/xie_qi_chao" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">解启超</a></span>
                                        </div>
                <div class="text"><span>发布了317 篇原创文章</span> · <span>获赞 48</span> · <span>访问量 3万+</span></div>
            </div>
                            <div class="right-message">
                                        <a href="https://im.csdn.net/im/main.html?userName=xie_qi_chao" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                    </a>
                                                        <a class="btn btn-sm attented bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">已关注</a>
                                </div>
                        </div>
                </div>
</article>
发布了179 篇原创文章 · 获赞 180 · 访问量 7100

函数

函数介绍
函数定义
函数的调用
函数的返回值
    总结
函数的参数
    参数
    参数的分类
        位置参数
        关键字参数
        混合参数
        总结
        动态接收位置参数
        动态接收关键字参数
函数的注释
名称空间
函数的嵌套
gloabal、nonlocal
    global 宗旨
    nonlocal宗旨
内置函数
    作用域相关
        locals()
        globals()
    迭代器相关
        range()
        next()
        iter()
    字符串类型代码的执行
        eval()
        exec()
    输入和输出相关
        input()
        print()
    内存相关
        hash()
        id()
    文件操作相关
        open()
    帮助
        help()
    调用相关
        callable()
    查看内置属性
        dir()
    基础数据类型相关
        数字相关
        数学运算
        数据结构相关
    数据集合
    其他相关
    lambda
    sorted
    filter
    map
    reduce

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

函数介绍

我们目前为止,已经可以完成一些软件的基本功能了,那么我们来完成这样一个功能:约x

我们先要约会,首先应该把手机拿出来打开聊天软件,然后问她约不约,等等….

用之前的学到知识怎么实现这个过程

pint("拿出手机")
print("打开陌陌")
print("找个漂亮的妹子")
print("问她,约不约啊!")
print("ok 走起")

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

ok so easy我们已经完成了对一个功能的描述,那么问题来了,我还想在约一次怎么搞,是不是就是在写一遍

# 约一次
pint("拿出手机")
print("打开陌陌")
print("找个漂亮的妹子")
print("问她,约不约啊!")
print("ok 走起")
# 再约一次
pint("拿出手机")
print("打开陌陌")
print("找个漂亮的妹子")
print("问她,约不约啊!")
print("ok 走起")

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

ok 非常简单搞定了,但是我还想约上个10次8次的,怎么搞,加个循环不就行了吗?

while True:
    pint("拿出手机")
    print("打开陌陌")
    print("找个漂亮的妹子")
    print("问她,约不约啊!")
    print("ok 走起")

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这样看似实现了但是也不能一直约吧,人还是要有节制的,约完了总是不放心,去医院看看吧.没问题就继续约

也就是想什么时候约就什么时候约,这可怎么实现啊??有点难住我胡汉三了.

好了说到这 我们就这样做,把约这个事,先计划好,然后按照安排好的流程.在需要约的时候 把这个约的流程拿出来执行以下就好了.

def yue():
    print('拿出手机')
    print('打开陌陌')
    print('找个漂亮妹子')
    print('问她约不约')
    print('ok,走起')

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

那么这里.我们可以先去定义一个事情或者是功能,等到需要的时候直接去用就好了.

聪明的你也猜到了这就是函数,是的它就是函数.那这个东西怎么用啊??
函数定义

def 是python中关键字主要用来定义函数的

yue这个是函数的名字

()这个括号是个神奇的东西,咱们后边会详细盘它
冒号是表示咱们这个语句写完了

细心的人看到怎么print都在里边,是的怎么要有一个缩进 缩进就是4个空格 缩进的意思里边的代码都是函数下边的代码

我们现在就来实现刚刚我们说的定义一个约x功能:

def yue():
    print("拿出手机")
    print("打开陌陌")
    print("找一个漂亮的妹子")
    print("问她,约不约啊")
    print("ok 走起")

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
哦了,这就定义完了,但是这个时候我们去执行,会发生什么现象? 什么都没有发生.因为我只定义了一个函数.但是还没有执行过这个函数.
函数的调用

使用函数名加小括号就可以调用了 写法:函数名() 这个时候函数的函数体会被执行

# 调用yue函数
def yue():
    print("拿出手机")
    print("打开陌陌")
    print("找一个漂亮的妹子")
    print("问 约不约啊")
    print("ok 走起")
yue()   # 这是yue函数的调用

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述
现在就实现了约一次,我想要约几次我就只需要

yue()
yue()
yue()
yue()
yue()
yue()

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
直接调用定义好的函数就可以了
函数的返回值

咱们约完之后的得有个结果吧, 比如是约的萝莉,还是大妈啊总得有个结果,那么这个结果

怎么来描述和获得呢? 这就涉及到函数的返回值啦

执行完函数之后,我们可以使用return来返回结果

def yue():
    print("约你")
    print("约我")
    print("约他")
    return   
    print("约谁呀")    # 这句话不会被执行
yue()

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

函数中遇到return,此函数结束.不在继续执行

我们现在有return返回值,我们试试返回个东西

def yue():
    print("约你")
    print("约我")
    print("约他")
    return  "美女一枚"
yue()

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们现在返回了一个字符串,但是返回给谁了呢? 这个返回值返回给函数的调用者了,我们来看一下

def yue():
    print("约你")
    print("约我")
    print("约他")
    return '美女一枚'
girl =  yue()
print(girl)
结果:
约你
约我
约他
美女一枚

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

肯定好多朋友还是不明白上边怎么就打印美女一枚了,莫慌看下图:
在这里插入图片描述
定义了一个函数yue
调用函数
执行函数里的约你
执行函数里的约我
执行函数里的约他
返回给调用者一个字符串,这个调用者就是yue()
将返回的字符串通过一个等号赋值给白变量girl
打印变量girl的值

函数的返回值可以有多个结果:

def yue():   
    print("约你")   
    print("约我")   
    print("约他")   
    return "美女一枚", "萝莉一枚"
girl = yue()
print(type(girl))   # tuple

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

总结

1.遇到return,此函数结束,return后面的东西将不会在执行

2.return 返回值

关于返回值:

如果return什么都不写或者干脆就没写return,返回的结果就是None

如果return后面写了一个值,返回给调用者这个值

如果return后面写了多个结果,返回给调用者一个tuple(元祖),调用者可以直接使用解构获取多个变量

OK,完美 可以得到结果了 但是我们约的方式是不是有点问题啊?陌陌现在还能约到吗?约不到了 我们换探探 那要是过几天探探也不行了

是不是会有一个替代品,那你们想有一个替代的,你就需要去改代码.是不是有点不合适了 最好的方式是想用什么约就用什么约 ok 我们也是可以实现的 ,我们就要在函数后边的括号里搞点事情了.
函数的参数

参数,也就是函数括号里的内容 函数在调用的时候指定一个具体的变量的值 就是参数.写法如下:

def 函数名(参数):
    函数体

  
  
  • 1
  • 2

我们应该把代码改一下,能够实现我刚说的那种效果

def yue(chat):
    print("拿出⼿手机")
    print("打开"+chat)
    print("找个漂亮的妹⼦子")
    print("约不不约")
yue("陌陌")
yue("微信")
yue("探探")
结果:
拿出手机
打开陌陌
找个漂亮的妹⼦
约不约
拿出⼿机
打开微信
找个漂亮的妹⼦
约不约
拿出手机
打开探探
找个漂亮的妹⼦
约不约 
搞定了. 我们在调用yue的时候给chat一个值. 然后再执行函数体.

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

参数

1.形参

写在函数声明的位置的变量叫形参,形式上的一个完整.表示这个函数需要xxx

2.实参

在函数调用的时候给函数传递的值.加实参,实际执行的时候给函数传递的信息.表示给函数xxx

3.传参

给函数传递信息的时候将实际参数交给形式参数的过程被称为传参.

def yue(chat):    # chat  形参
    print("拿出手机")
    print("打开"+chat)
    print("找个漂亮的妹子")
    print("约不约")
yue("陌陌")     # 实参
len("字符串")    # "字符串"在这里就是实参
print("麻花藤")    # "麻花藤"就是实参

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

参数的分类
位置参数

约到现在,有没有想过这么一个问题,啥样的约么? 哪里的都约么? 不一定吧.比如我现在在北京,我很寂寞,我喜欢小姐姐

alex 在泰国,很寂寞 人妖就行了 .需求是不一样的 而我们现在的函数没有这些功能 那怎么办呢? 很简单 多来几个参数就好了

def yue(chat,addr,age):    # chat  形参
    print("拿出手机")
    print("打开"+chat)
    print("找个" + addr +"附近漂亮的" + str(age) + "岁妹子")
    print("约不约")
yue("陌陌","北京",18)    # 实参
结果:
拿出手机
打开陌陌
找个北京附近漂亮的18岁妹子
约不约

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上述代码分析: 在访问yue()的时候,我们按照位置的顺序分别把”陌陌”,”北京”,18赋值给了chat,addr,age,在传参过程中.系统会按照位置把实参赋值到形参.

形参就是一个变量名,实参就是值 传参就是在赋值
练习

编写函数,给函数传递两个参数a,b a,b相加 返回a参数和b参数相加的和

def f(a,b):
    c = a+b
    return c
num_sum = f(5,8)
print(num_sum)
结果: 13

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

编写函数,给函数传递两个参数a,b 比较a,b的大小 返回a,b中最大的那个数

def f(a,b):
    if a>b:
        return a
    else:
        return b
num_sum = f(5,8)
print(num_sum)
结果:8

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

比较大小的这个写法有点麻烦,我们在这里学一个三元运算符

def f(a,b):
    c = a if a > b else b  #当a>b就把a赋值给c,否则就把b赋值给c
    return c
msg = f(5,7)
print(msg)
结果:
7

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

关键字参数

位置参数好不好呢? 如果是少量的参数还算OK, 没有问题. 但是如果函数在定义的时候参数非常多怎么办? 程序员必须记住, 我有哪些参数, 而且还有记住每个参数的位置, 否则函数就不能正常调用了. 那则么办呢? python提出了一种叫做关键字参数. 我们不需要记住每个参数的位置. 只要记住每个参数的名字就可以了

def yue(chat, address, age):
    print("拿出手机")
    print("打开"+chat)
    print("找个"+address+"附近漂亮的"+str(age)+"岁妹子")
    print("约不约")
yue(chat="微信", age=18, address="北京")       # 关键字参数.
结果:
拿出手机
打开微信
找个北京附近漂亮的18岁妹子
约不约

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

搞定, 这样就不需要记住繁琐的参数位置了.
混合参数

可以把上面两种参数混合着使用. 也就是说在调用函数的时候即可以给出位置参数, 也可以指定关键字参数.

# 混合参数 
yue("微信", age=18, address="上海")    # 正确.第一个位置赋值给chat, 后面的参数开始指定关键字.
yue(age="18", "微信", address="广州")  # 错误, 最开始使用了关键字参数, 那么后面的 微信的位置就串了, 容易出现混乱

  
  
  • 1
  • 2
  • 3

注意: 在使用混合参数的时候, 关键字参数必须在位置参数后面
总结

综上: 在实参的⾓角度来看. 分为三种:

位置参数
关键字参数
混合参数, 位置参数必须在关键字参数前面

  
  
  • 1
  • 2
  • 3

位置参数:

位置参数,按照位置来赋值,到目前为止,我们编写的函数都是这种

def yue(chat, address, age):
    print("拿出手机")
    print("打开"+chat)
    print("找个"+address+"附近漂亮的"+str(age)+"岁妹子")
    print("约不约")

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

默认值参数:

在函数声明的时候, 就可以给出函数参数的默认值. 在调用的时候可以 给出具体的值, 也可以不给值, 使⽤用默认值. 比如, 我们录入咱们班学生的基本信息. 通过调查发现. 我们班大部分学生都是男生. 这个时 候就可以给出⼀一个sex=’男’的默认值.

def stu_info(name, age, sex='男'):
    print("录入学生信息")
    print(name, age, sex)
    print("录入完毕")
stu_info("张强", 18)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

注意:必须先声明在位置参数,才能声明关键字参数

综上:在形参的角度来看

位置参数
默认值参数(大多数传进来的参数都是一样的, 一般用默认参数

  
  
  • 1
  • 2

函数参数-动态参数

形参的第三种:动态参数

首先我们来回顾下位置参数

def eat(a,b,c):
    print('我想吃%s%s%s'%(a,b,c))
eat('大米饭','中米饭','小米饭')

  
  
  • 1
  • 2
  • 3

现在有个问题,你们看我这体型也知道吃的不止这些,数量也没有写,这时我们就要用到动态参数
动态接收位置参数

在参数位置用*表示接受任意参数

def eat(*args):
    print('我想吃',args)
eat('大米饭','中米饭','小米饭')  # 收到的结果是一个tuple元祖

  
  
  • 1
  • 2
  • 3

动态接收参数的时候要注意: 动态参数必须在位置参数后面

def eat(*args,a,b):
    print('我想吃',args,a,b)
eat('大米饭','中米饭','小米饭')
结果:
TypeError: eat() missing 2 required keyword-only arguments: 'a' and 'b'
# eat函数在调用的时候发现缺少俩个位置参数没有进行传递

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通过上述代码发现一个问题就是,我们明明给了多个参数,为什么还会提示参数未传递呢?

原因就是因为这个在搞鬼 把所有的位置参数都给接受了,所有会报错.我们尝试着把a,b放在的前面试试

def eat(a,b,*args):
    print('我想吃',args,a,b)
eat('大米饭','中米饭','小米饭')
结果:
我想吃 ('小米饭',) 大米饭 中米饭

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

动态接收参数的时候要注意:动态参数必须在位置参数后面

那默认值参数呢?

def eat(a,b,c='白菜',*args):
    print('我想吃',a,b,c,args)
eat('豆腐','粉条','猪肉','大葱')
结果:
我想吃 豆腐 粉条 猪肉 ('大葱',)  # 我们定义好的白菜没有生效,被猪肉给覆盖了

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

我们发现默认值参数写在动态参数前面,默认值的参数是不会生效的

def eat(a,b,*args,c='白菜'):
    print('我想吃',a,b,args,c)
eat('猪肉','粉条','豆腐','大葱')
结果:
我想吃 猪肉 粉条 ('豆腐', '大葱') 白菜  # 这样默认参数就生效了

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

这个时候如果你不给出关键字传参,那么你的默认值是永远都生效的

注意: 形参的顺序: 位置参数 , 动态参数 , 默认参数
动态接收关键字参数

在python中可以动态的位置参数,但是这种情况只能接收位置参数无法接收关键字参数,在python中使用*来接收动态关键字参数

def func(**kwargs):
    print(kwargs)     
func(a=1, b=2, c=3)
结果:
{'a': 1, 'b': 2, 'c': 3}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

动态关键字参数最后获取的是一个dict字典形式

顺序的问题, 在函数调用的时候, 如果先给出关键字参数, 则整个参数列表会报错.

def func(a,b,c,d):
    print(a,b,c,d)
func(1,2,c=3,4)
结果:
  File "D:/python_object/path2/test.py", line 806
    func(1,2,c=3,4)              ^
SyntaxError: positional argument follows keyword argument

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

关键参数必须要放在位置参数后边,由于实参是这个顺序,所以形参接收的时候也是这个顺序.也就是说位置参数必须在关键字参数前面.动态接收关键字参数也要在后面

最终顺序:

位置参数 > args(动态位置参数) > 默认值参数 > *kwargs(动态默认参数)

这四种参数可以任意的使用

如果想接收所有的参数:

def func(*args,**kwargs):
    print(args,kwargs)
func(1,23,5,a=1,b=6)

  
  
  • 1
  • 2
  • 3

动态参数还可以这样传参:

lst = [1,4,7]
# 方法一
def func(*args):
    print(args)
func(lst[0],lst[1],lst[2])
# 方法二
def func(*args):
    print(args)
func(*lst)  
# 在实参的位置上用*将lst(可迭代对象)按照顺序打散
# 在形参的位置上用*把收到的参数组合成一个元祖

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

字典也可以进行打散,不过需要**

dic = {'a':1,'b':2}
def func(**kwargs):
    print(kwargs)
func(**dic)

  
  
  • 1
  • 2
  • 3
  • 4

函数的注释

def eat(food,drink):
    '''
    这里描述这个函数是做什么的.例如这函数eat就是吃
    :param food:  food这个参数是什么意思
    :param drink: drink这个参数是什么意思
    :return:  执行完这个函数想要返回给调用者什么东西
    '''
    print(food,drink)
eat('麻辣烫','肯德基')

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在外部查看函数的注释 函数名.doc

print(eat.__doc__)  #函数名.__doc__
结果:
    这里描述这个函数是做什么的.例如这函数eat就是吃
    :param food:  food这个参数是什么意思
    :param drink: drink这个参数是什么意思
    :return:  执行完这个函数想要返回给调用者什么东西

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

名称空间

在python解释器开始执行之后, 就会在内存中开辟一个空间, 每当遇到一个变量的时候, 就把变量名和值之间的关系记录下来, 但是当遇到函数定义的时候, 解释器只是把函数名读入内存, 表示这个函数存在了, 至于函数内部的变量和逻辑, 解释器是不关心的. 也就是说一开始的时候函数只是加载进来, 仅此而已, 只有当函数被调用和访问的时候, 解释器才会根据函数内部声明的变量来进行开辟变量的内部空间. 随着函数执行完毕, 这些函数内部变量占用的空间也会随着函数执行完毕而被清空.

def fun():   
    a = 10   
    print(a)
fun()
print(a)    # a不存在了已经..

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

​ 我们给存放名字和值的关系的空间起一个名字叫: 命名空间. 我们的变量在存储的时候就 是存储在这片空间中的.

​ 命名空间分类:

​ 1. 全局命名空间—> 我们直接在py文件中, 函数外声明的变量都属于全局命名空间

​ 2. 局部命名空间—> 在函数中声明的变量会放在局部命名空间

​ 3. 内置命名空间—> 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间

加载顺序:

内置命名空间
全局命名空间

  
  
  • 1
  • 2

​ 3. 局部命名空间(函数被执行的时候)

取值顺序:

​ 1. 局部命名空间

​ 2. 全局命名空间

​ 3. 内置命名空间

a = 10
def func():  
    a = 20   
    print(a)
func()  # 20

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

作用域: 作用域就是作用范围, 按照生效范围来看分为 全局作用域 和 局部作用域

全局作用域: 包含内置命名空间和全局命名空间. 在整个文件的任何位置都可以使用(遵循 从上到下逐⾏执行).

局部作用域: 在函数内部可以使用.

作⽤域命名空间:

全局作⽤用域: 全局命名空间 + 内置命名空间
局部作⽤用域: 局部命名空间 

  
  
  • 1
  • 2

我们可以通过globals()函数来查看全局作⽤用域中的内容,也可以通过locals()来查看局部作 ⽤用域中的变量量和函数信息

a = 10
def func():   
    a = 40   
    b = 20   
    print("哈哈")   
    print(a, b)        
    print(globals())    # 打印全局作用域中的内容   
    print(locals())     # 打印局部作用域中的内容
func()

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述
函数的嵌套

只要遇见了()就是函数的调用. 如果没有()就不是函数的调用
函数的执行顺序

猜你喜欢

转载自blog.csdn.net/weixin_46575696/article/details/104959645
今日推荐