当前位置: 首页 > news >正文

06、python 系列之 函数

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

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

教程简介

  • 1、阅读对象

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

  • 2、教程难度

    初级

  • 3、demo 地址:github.com/githubchen0… 如果喜欢就给个 star 吧

正文

一、什么是函数

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))
复制代码

运行查看结果:

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()

复制代码

运行查看结果:

五、匿名函数

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

在 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
复制代码

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

相关文章:

  • ASP.NET Linux部署(2) - MS Owin + WebApi + Mono + Jexus
  • 并查集-----hrbust 1073
  • Unity LayerMask 的位运算
  • 搭建千万PV高可用系统—DNS
  • eclipse再见,android studio 新手入门教程(一)基本设置
  • CentOS 7.2 安装jdk1.8.x版本
  • UVA 725 division【暴力枚举】
  • angularjs $$phase
  • 安装PHP5,安装PHP7
  • CSS 为什么这么难学?
  • sql server 索引总结一
  • 『TensorFlow』读书笔记_Word2Vec
  • Android UI进阶之旅15 SVG的使用
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • Android的一些命名规范
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 0基础学习移动端适配
  • 3.7、@ResponseBody 和 @RestController
  • AHK 中 = 和 == 等比较运算符的用法
  • Android系统模拟器绘制实现概述
  • es6要点
  • java中的hashCode
  • js作用域和this的理解
  • Kibana配置logstash,报表一体化
  • React-生命周期杂记
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • Webpack 4 学习01(基础配置)
  • XForms - 更强大的Form
  • 如何选择开源的机器学习框架?
  • 数组大概知多少
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 异步
  • 7行Python代码的人脸识别
  • elasticsearch-head插件安装
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • #{}和${}的区别是什么 -- java面试
  • (C语言)fread与fwrite详解
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (附源码)计算机毕业设计高校学生选课系统
  • (十)T检验-第一部分
  • (学习日记)2024.01.19
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)h264中avc和flv数据的解析
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .NET Framework杂记
  • @Pointcut 使用
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [acm算法学习] 后缀数组SA
  • [BUAA软工]第一次博客作业---阅读《构建之法》
  • [Hadoop in China 2011] Hadoop之上 中国移动“大云”系统解析