06、python 系列之--函数

fun.png

版权声明:本文为博主原创文章,未经博主允许不得转载。

PS:转载请注明出处
作者: TigerChain
地址: http://www.jianshu.com/p/105ee1470d02
本文出自 TigerChain简书 Python 系列

教程简介

  • 1、阅读对象

本篇教程适合新手阅读,老手直接略过

正文

一、什么是函数

1、定义

在编程中,函数是对实现特定功能,并且可以重复使用的一个代码片段。比如 python 的内置函数 print(),函数的作用:

  • 1、封装代码
  • 2、降低耦合
  • 3、方便复用
  • 4、方便阅读

2、定义函数的格式

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

ps:函数体以 : 号开始,并且缩进

比如定义一个 返回 a+b 的函数

def add(a,b):
    return a+b

这样就自定义了一个函数。

函数调用:add(5,6) 即可

demo1:将后一个姓名列表添加到第一个列表的末尾


names = ["tigerchain","xiaoming","liubing"]

print("原始的姓名列表是:%s"%names)

# �定义函数 
def appendList(lists):
    names.append(lists)
    print("添加后的姓名列表是:%s"%names)

new_names = ["sulei","xiaozhang"]
appendList(new_names)

print("最终的姓名列表是: %s "%names)

运行查看结果:

▶ python 01、函数的基本用法.py
原始的姓名列表是:['tigerchain', 'xiaoming', 'liubing']
添加后的姓名列表是:['tigerchain', 'xiaoming', 'liubing', ['sulei', 'xiaozhang']]
最终的姓名列表是: ['tigerchain', 'xiaoming', 'liubing', ['sulei', 'xiaozhang']]

二、函数的参数

1、形参和实参

首先我们要明确一点 python 中传递参数是按址传递的,也就是把变量的引用传递进去,而不是按值传递

  • 1、定义函数后面的()中的参数称为形参
  • 2、调用函数的方法,传递给函数的参数称为实参

比如:定义一个函数

def addsub(a,b):
    return a+b

其中 a 和 b 是形参

调用方法 addsub(1,5),其中 1,5 就是实参

2、理论上函数可以传递无数个参数,但是不建议这样干,如果多个参数,就想办法抽取多个方法

def 方法名(形参1,形参2,...,形参n)

demo2:定义一个函数,输入三条边,看其能不能组成三角形

def sanjiao(x,y,z):#实际开发中不要使用拼音作为函数名
    if(x+y>z and x+z>y and y+z>x):
        print("%d,%d,%d 可以组成三角形"%(x,y,z))
        if(x==y==z):
            print("并且这是一个等边三角形")
        elif(x==y or y==z or x==z):
            print("并且这是一个等腰三角形")
        elif(x*x+y*y==z*z or y*y+z*z==x*x or x*x+z*z==y*y):
            print("并且这是一个直角三角形")
        else:
            print("并且这是一个普通的其解形")
    else:
        print("不好意思,你三角形的概念好好学学吧,不能构成三角形")

print("请输入三角形的三条边")

x = raw_input("第一条边:")
y = raw_input("第二条边:")
z = raw_input("第三条边:")

sanjiao(int(x),int(y),int(z))

运行查看结果:

fun_sanjiao.gif

demo3:输入三个数,输出最大数

def getMax(x,y,z):
    max = x
    if(y>max):
        max=y
        if(z>max):
            max=z

    return max

a = raw_input("请输入第一个数:")
b = raw_input("请输入第二个数:")
c = raw_input("请输入第三个数:")

print("%d,%d,%d 中最大的数是:%d"%(int(a),int(b),int(c),getMax(int(a),int(b),int(c))))

运行查看结果:

▶ python 02、形参和实参.py
请输入第一个数:4
请输入第二个数:8
请输入第三个数:0
4,8,0 中最大的数是:8

3、变量的作用域

定义在函数体中的变量只能在本函数中有效,出了函数以后就不能被访问

demo1:变量的作用域

def add(x,y):
    z = x+y
    print z
def new_add():
    print("===1====")
    z+=4
    print("===3===")
    print z

add(1,2)
new_add()

运行查看结果:

▶ python 04、变量作用域.py
3
===1====
Traceback (most recent call last):
  File "04、变量作用域.py", line 13, in <module>
    new_add()
  File "04、变量作用域.py", line 8, in new_add
    z+=4
UnboundLocalError: local variable 'z' referenced before assignment

挂掉了,问题出在 new_add() 方法中的 z+=4,看 error 大概意思就是不能访问之前在 add 方法中定义的 z 变量

三、函数的文档「注释」

我们知道多行注释使用 ''' ''' ,函数的文档是什么呢?就是用来描述函数的语句,但是不会被编译,不能使用 # 注释

demo1:对 add 函数作文档说明

'''
    demo1:对add 函数作文档说明
'''
def addFun(a,b):
    ''' 这个函数是返回两个整数的和 '''
    return a+b
'''help(addFun) 显示方法体中的文档说明'''
print __doc__

运行查看结果:

▶ python 03、函数的文档.py


    demo1:对add 函数作文档说明

2、局部变量和全局变量

1、局部变量:局部变量是针对方法而说的,没有方法局部变量就没有意义,定义在方法体中的变量我们称为局部变量,局部变量只能在方法体中被仿问,在方法体外是不能被仿问的。

2、全局变量:定义在方法调用之前的变量,我们称为全局变量,全局变量,所有方法都要以仿问

demo2:以下 demo1 中的 x 是修改全局变量 x 还是定义了一个局部变量 x 呢?

x = 0
def demo1():
    x = 100
    print("x 的值是%d "%x)
def demo2():
    print("x 的值是%d "%x)
    pass

demo1()
demo2()

运行查看结果:

▶ python 04、变量作用域.py
x 的值是100
x 的值是0

可以看到在 demo1 方法中的变量 x 就是定义一个局部变量,对全局变量 x 一点毛影响也没有。那么,我们如何让 demo1 中的 x 就是修改全局变量 x 呢?,使用 global 关建字来声明即可

稍微修改上面的代码在 demo1 x = 100 之前加入 global x

global x
x = 100

继续运行查看结果:

▶ python 04、变量作用域.py
x 的值是100
x 的值是100

可以看到我们成功的修改了全局变量。

demo3:可变类型变量例子

# 定义一个列表「可变类型」
a = [1,2,3,4]

def demo1():
    a.append(5)
    print("a 的内容是 %s"%a)
def demo2():
    print("a 的内容是 %s"%a)
    pass
demo1()
demo2()

运行查看结果:

▶ python 04、变量作用域.py
a 的内容是 [1, 2, 3, 4, 5]
a 的内容是 [1, 2, 3, 4, 5]

我们可以看到,执行 demo1() 我们就修改了列表,所以如果声明的是列表类型的变量,我们就可以直接修改

四、函数的参数(二)

1、缺省参数

缺省参数,就是我们可以给函数默认设置参数,格式如下:

def 方法名(参数1,参数2,...,参数n = 值)

PS:在这里一定要注意一点,缺省参数一定要放在参数列表的最后面

demo1:定义函数 demo1(),并且带有两个参数姓名和年龄,并且姓名是默认值是'TigerChain',输入看结果

# -*- coding:utf-8 -*-

'''
    demo1:缺省参数 
'''

def demo1(age,name='TigerChain'):
    print("name = %s"%name)
    print("age = %d"%age)
demo1(12)

运行查看结果:

▶ python 05、函数的参数.py
name = TigerChain
age = 12

从上面的 demo 中我们可以看到,如果我们没有给默认值的参数传值的话,就会使用默认值,如果我们传递了呢?答案肯定是按传递的值显示,修改上面代码,只是把调用方法改为 demo(12,'TigerChain001')

查看结果

▶ python 05、函数的参数.py
name = TigerChain001
age = 12

2、不定长参数

我们知道函数的参数理论上可以有无数个,如果一个函数要处理比声明时更多的参数,这就叫做不定长参数,在传递的时候才会确定参数的多少,格式如下:

def 方法名(参数1,参数2,*参数3,**参数4):
    方法体

PS:其中参数 1 和参数 2 没有什么说的,就是普通的参数,参数 3 传递进来的会被录作元组存起来,参数 4 「两个 **」传递的是字典

demo2:可变参数 1

def demo2(param1,param2,*param3):
    print "param1 = ",param1
    print "param2 = ",param2
    print "param3 = ",param3
demo2(1,2,3,4,5,6)

运行查看结果:

▶ python 05、函数的参数.py
param1 =  1
param2 =  2
param3 =  (3, 4, 5, 6)

我们可以看到 3,4,5,6 被当作元组传传递过来

  • 我们修改上面的代码
def demo3(param1,param2,*param3,**param4):
    print "param1 = ",param1
    print "param2 = ",param2
    print "param3 = ",param3
    for key,value in param4.items():
        print key ," = ",value

demo3(1,2,3,4,5,name='TigerChain',age=12,address='中国')

运行查看结果:

▶ python 05、函数的参数.py
param1 =  1
param2 =  2
param3 =  (3, 4, 5)
age  =  12
name  =  TigerChain
address  =  中国
  • 续续修改上面的代码,我们把调用方式改一下
c = (7,8,9)
d = {"name":"TigerChain","age":12,"sex":"男"}
demo3(1,2,3,c,d)

运行查看结果:

▶ python 05、函数的参数.py
param1 =  1
param2 =  2
param3 =  (3, (7, 8, 9), {'age': 12, 'name': 'TigerChain', 'sex': '男'})

我们可以看到 c 「元组」 和 d 「字典」 整体被当做元组传到 param3 中了

  • 再修改上面的代码

这次我们在上面代码基础上,只是修改调用方式

demo3(1,2,3,*c,**d)

运行查看结果:

▶ python 05、函数的参数.py
param1 =  1
param2 =  2
param3 =  (3, 7, 8, 9)
age  =  12
name  =  TigerChain
sex  =  男

3、模拟用户注册登录「函数版」

demo:用户注册登录,并且用户名密码输入错误三次,锁定

# -*- coding:utf-8 -*-

'''
    这是一个函数版模拟用户注册登录
'''

# 定义保存用户名和密码的字典
userInfo = {}

# 是否登录的标志
islog = False

# 注册方法
def register():
    uname = raw_input("添加用户名: ")
    upass = raw_input("添加密码: ")
    userInfo[str(uname)] = upass
    print("注册成功")

# 登录方法
def login():
    for i in range(3):
        global islog
        if(islog):
            break
        username_input = raw_input('请输入用户名:')
        userpass_input = raw_input("请输入密码:")
        login_count = 2-i  # 判断还能输入多少次。
        for key in userInfo.keys():
            if(str(username_input) == key and userInfo[key]== userpass_input):
                print("欢迎 %s 登录"%key)
                islog = True
                break
            else:
                # 最后一次是 0 不再提示
                if login_count != 0:
                    print("用户名或密码错误,还可以输入 %d 次"%login_count)
        if(i==2):
            print("登录超过 3 次,半个小时后再登录")


register()
login()

运行查看结果:

login_fun.gif

五、匿名函数

什么是匿名函数,顾名思义就是没有名字的函数

在 python 中使用 lambda 关建字来创建匿名函数「lambda 是一个表达多,不是一个语句」,格式如下:

lambda [arg1 [,arg2,.....argn]]:expression

demo1:使用 lambda 来创建一个加法运算函数

# 定义一个 labmda 表达式
sum = lambda a,b:a+b
print sum(1,4)

运行查看结果:

▶ python 07、匿名函数.py
5

demo2:使用 lambda 作为方法参数「函数式编程」

# 定义一个函数,参数分别是普通变量和一个函数
def fun(a,b,func):
    return func(a,b)
result = 0

e = ''

while True:
    if e=='e':
        break
    if e == 'c' or e =='':
        a = int(raw_input("请输入一个整数 a = "))
        b = int(raw_input("请输入一个整数 b = "))
        calc = raw_input("选择 + - * / 其中一项:")
        # 加法运算
        if calc == '+':
            result = fun(a,b,lambda a,b:a+b)
        # 减法运算
        elif calc == '-':
            result = fun(a,b,lambda a,b:a-b)
        # 乘法运算
        elif calc == "*":
            result = fun(a,b,lambda a,b:a*b)
        else:
        # 除法运算
            if b==0:
                print("被除数不能为0")
                continue 
            result = fun(a,b,lambda a,b:a/b)
        print result
        e = raw_input("退出请输入 e 继续请输入 c : ")

运行查看结果:

python 07、匿名函数.py
lambda.gif

到此为止,我们就把函数的一些方法和功能基本介绍完了

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

推荐阅读更多精彩内容

  • //Clojure入门教程: Clojure – Functional Programming for the J...
    葡萄喃喃呓语阅读 3,604评论 0 7
  • 有些人这样说的,农村的孩子与城市里的孩子相比,缺少礼貌,的确,我经过观察确实如此。在小的时候,城里的父母经常...
    心如山亦如水阅读 261评论 0 0
  • 经过这一段时间的学习,让我对创意有了更深的了解,现在我按个人的理解,重新定义了创意大师,总结了创意的三种境界,简称...
    醒时做梦阅读 367评论 0 2
  • 友人向我推荐夏达的《子不语》最近看了看,有点感触。权且写下来当做记忆吧,也可说是感思。 终于可以表达一下自己的看法...
    曾经未来的我阅读 604评论 0 0
  • 第一篇是罗丹琳小朋友写的放风筝日记,这个小朋友写出了这个冬天放风筝的别样心情,谁说冬天就不适合放风筝呢 第二篇...
    fdeceb686cba阅读 229评论 0 0