十、函数part1

1.什么是函数?

函数就是具备某一功能的工具。

工具的使用:

实现准备好工具 =========》函数定义

遇到应用场景拿来就用 =======》函数的调用

2.为什么要有函数?

1、程序的组织结构不清晰,可读性差

2、如果要用到重复功能,只能拷贝功能的实现代码=》代码冗余

3、可扩展性差

3.如何用函数?

函数的使用原则:先定义后使用

定义函数:

def 函数名(参数1,参数2,参数3.....):

    代码1

    代码2

    ......

    return 返回值

调用函数:

    函数名(值1,值2,值3......)

定义一个函数和定义一个变量是类似的,申请内存空间把函数的代码保存起来,然后把内存地址绑定给函数名=》函数名=函数的内存地址

def sayhi():

    print ("="*10)

    print ("hellow")

    print ("="*10)

调用函数就是函数名() =》函数的内存地址(),会触发函数体代码的运行

sayhi()

二、定义函数的三种方式

2.1 无参函数

def login:

    inp_name = input("your name:").strip()

    inp_pwd = input("your pwd:").strip()

    if inp_name=="egon" and inp_pwd=="123":

        print(""登陆成功!)

    else:

        print("登陆失败!")

2.2 有参函数

def sayhi(n,i):

print(n*i)

sayhi("=",3)

def incharge(x,y):

    if x>y:

        print(x)

    else:

        print(y)

incharge(3,4)

2.3 空函数

def func():

     ...或者pass#适合刚刚开始写代码,对于没有逻辑的代码用这个实现

三、函数的调用

return:函数内可以有多个return,但只要执行一次函数就立刻结束,并会把return后的值当作本次调用的结果返回。

函数可以有三种形式的返回值

1、return值:返回的就是该值的本身

2、return 值1,值2,值3:返回一个元组

3、没有return:默认返回None

def salary(x,y):

    if x>y:

        return(x)

    else:

        return(y)

salary_year = salary(2.1,1.8)*12

print(salary_year)#计算年薪需要返回值,所以用return

四:函数调用的三种格式

1.语句形式:单纯地调用一下函数就完了

def sayhi(n,i):

    print(n*i)

sayhi("=",3)

2.表达式形式

def salary(x,y):

    if x>y:

        return(x)

    else:

        return(y)

salary_year = salary(2.1,1.8)*12

print(salary_year)

3. 把函数的调用当作值传送给另外一个函数

def salary(x,y):

    if x>y:

        return(x)

    else: 

        return(y)

print(salary(11,22))

总结:函数的使用一定要分两个阶段去看:

1、定义阶段:只检测语法,不执行代码

2、调用阶段:执行函数体代码

如果发生的语法错误,定义阶段就会立马检测出来

如果发生的不是语法错误,而是逻辑错误,只能在调用阶段检测到

五、函数的参数分为两大类:

1、形参:在定义函数时,括号内定义的变量名,称之为形式参数,简称形参=》变量名

2、实参:在调用函数时,括号内传入的值,称之为实际参数,简称实参=》变量值

六、在python中参数的种类

1、位置参数:

(1)在函数定义阶段按照从左到右的顺序依次定义形参(变量名),称之为位置形参。

特点:必须被传值(少一个不行多一个也不行)

(2)在函数定义阶段按照从左到右的顺序依次定义实参(传入的变量值),称之为位置实参

特点:按照位置一一对应的传值

2、关键字实参:在函数调用阶段按照key = value的形式为指定的形参名传值,该形式称之为关键字实参

特点:在传值时可以完全打乱顺序,但是仍然能够指名道姓的为指定形参传值。

def func(name,age):

    print(name,age)

func(age = 18,name ="egon")

注意:1.可以混用位置实参和关键字实参,但是位置实参必须放在关键字实参的前面

2.不能为同一个形参重复赋值

3、默认形参:在函数定义阶段就已经为某个形参赋值了,该形参称之为有默认值的形参,简称默认形参。

特点:定义阶段就已经被赋值意味着在函数调用阶段可以不用为其赋值。

注意:

1.默认形参应该跟在位置形参的后面

2.默认形参的值通常应该是不可变类型

3.默认形参的值只在函数定义阶段被赋值一次,函数定义之后的改变对默认形参没有影响


七、*与**在形参与实参中的应用

1、可变长参数

可变长指的是参数的个数不固定

站在实参的角度,实参是用来为形参赋值的,如果实参的个数不固定,那么必须要有对应的形参能够接收那些溢出的实参

1.1在形参名前面加*:*会把溢出的位置实参存成元组,然后赋值其后的形参名

def func(x,*y):

print(x)

print(y)

func(1,2,3,5)

1.2在形参名前面加**:**会把溢出的关键字实参存成字典,然后赋值其后的形参名

def func(x,**y):

print(x)

print(y)

func(1,a=1,b=2,c=3)

1.3在实参前加*:*会把其后的值打散成位置实参

def func(x,y,z):

print(x)

print(y)

print(z)

a = [1,2,3]

func(*a)

1.4在实参前加**:**会把其后的值打散关键字实参

def func(x,y,z):

print(x)

print(y)

print(z)

dic = {"x":1,"y":2,"z":3}

func(**dic)

1.5 在形参混用*和**

def index(x,y,z,a,b,c):

    print(x,y,z,a,b,c)

def func(*d,**e):

    index(*d,**e)

func(1,2,3,a=111,b=222,c=333)

命名关键字形参(**)

def func(x, y=222, *args, n=777,m, **kwargs):  # m,n必须按照关键字实参的格式为其赋值

    print(x)  # 1

    print(y)  # 2

    print(args)  # (3,4,5)

    print("m===>", m)

    print("n===>", n)

    print(kwargs)

# func(1,2,3,4,5,6666666)

# func(1,2,3,4,5,m=6666666)

func(1, 2, 3, 4, 5, n=88888,m=6666666, a=11, b=22, c=33)

八、函数对象指的是函数可以被当成变量去使用

def foo():# foo = 函数的内存地址

    print('from foo')

1 可以被赋值

f = foo

print(fis foo)

f()

2 可以当作参数传给一个函数

def bar(func):

print(func)

func()

bar(foo)

3 可以当成一个函数的返回值

def bar(func):

return func

res=bar(foo)

print(res)

4 可以当成容器类型的元素

l = [foo]

print(l)

l[0]()

示例:

def login():

    print('登录功能......')

def withdraw():

    print('提现功能......')

def transfer():

    print('转账功能......')

def recharge():

    print('充值功能')

func_dic={

"1": [login,"登录"],

    "2": [withdraw,"提现"],

    "3": [transfer,"转账"],

    "4": [recharge,"充值"]

}

while True:

    print("0    退出")

    for kin func_dic:

        print("%s    %s" %(k,func_dic[k][1]))

        choice =input("请输入你的指令编号: ").strip()

        if choice =="0":

            break

        if choicein func_dic:

            func_dic[choice][0]()

        else:

            print('输入的指令不存在') #利用函数对象使代码更加简洁

九、函数的嵌套

1.函数的嵌套调用

def bar():

    print('from bar')

def foo():

    print('from foo')

    bar()

foo()

案例:

def max2(x,y):

    if x > y:

        return x

    else:

        return y

def max4(a,b,c,d):

    res1 = max2(a,b)

    res2 = max2(res1,c)

    res3 = max2(res2,d)

    print(res3)

max4(1,2,3,4)#先定义一个比大小的函数,后面进行赋值操作时直接调用。

2 函数的嵌套定义

def f1():

    print('from f1')

    # f2 = 函数的内存地址

    def f2():

        print("from f2")

f1()

3.定义在函数内的函数特点是: 正常情况只能在函数体内调用

from math import pi

def circle(radius,mode=0):

    def perimiter(radius):

        return 2 * pi * radius

    def area(radius):

        return pi * (radius ** 2)

    if mode == 0:

        return perimiter(radius)

    elif mode == 1:

        return area(radius)

res1=circle(3,0)

res2=circle(3,1)

print(res1)

print(res2)

十、名称空间: 就是存放名字的地方

1 内置名称空间: 存放的是内置的名字,如print\input\len

      生命周期: 解释器启动则产生,解释器关闭则销毁

2 全局名称空间: 存放的是顶级的名字

      生命周期: python程序运行时则产生,python程序结束则销毁

3 局部名称空间:函数内的名字

      生命周期:调用函数时则产生,函数调用结束则销毁

名字的查找优先级:

从当前位置往外查找,如果当前是在局部:局部名称空间->全局名称空间->内置名称空间

从当前位置往外查找,如果当前是在全局:全局名称空间->内置名称空间

实例:

x =10

def msg():

    x =11

    def esg():

        x =12

        print(x)

    esg()

    print(x)

msg()

print(x)

一个非常重要的结论:名称空间的嵌套关系是函数定义阶段(即扫描语法时)就固定死的,与函数的调用位置无关

佐证:

x =111

def foo():

    print(x)

def bar(f):

    x=222

    f()

bar(foo)

l = ["aaa","bbb",[000,111,222]]

def msg():

l[2][0] =444

msg()

print(l)#中间的l是基于上面l的修改,所以输出的值为修改后的值。


全局范围/全局作用域:内置名称空间+全局名称空间

特点:全局存活,全局有效

局部范围/局部作用域:局部名称空间

特点:临时存活,局部有效

案例1:

x =10

def func():

    global x

    x=22

func()

print(x)

案例2:

x =10

def f1():

    x=111

    def f2():

        x=222

    f2()

print(x)

f1()

print(x)

案例3:nonlocal生命名字是来自于外层函数的(***)与案例2进行对比

x =10

def f1():

    x=111

    def f2():

        nonlocal x

        x=222

    f2()

print(x)

f1()

print(x)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,914评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,935评论 2 383
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,531评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,309评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,381评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,730评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,882评论 3 404
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,643评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,095评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,448评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,566评论 1 339
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,253评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,829评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,715评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,945评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,248评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,440评论 2 348