第五篇:Python函数基础篇
本篇介绍什么是函数、函数的特性、函数的定义、函数的调用、以及函数的参数、以及关于全局变量和局部变量的使用等等。
一、什么是函数:
函数是最基本的一种代码抽象方式,为了实现某种特定的功能而组织的带名字的代码块。
那为什么要使用函数呢?
1、避免代码的重复性,即函数的可以重复使用的。
2、保持代码的一致性,易于修改。即当函数被定义好,即可在很多地方为了实现相同或者相似的功能时可调用函数,而当这些功能发生改变时,我们只需修改该函数即可,不必麻烦的去修改每一处实现该功能的代码。
3、扩展性。
其实简单的来说:函数就行一个有着特定功能作用的工具,例如锤子或者扳手等,每当我们需要使用这些工具的时候,我们不需要临时请师傅制作这样一件工具,这样将会十分繁琐且消耗大量的时间,故我们仅需花费一定的代价去借用这些工具即可这些代价我们暂且可以把其称之为参数,而造这些工具的人为了怕别人不知道这些工具的使用,通常会给这些工具贴上使用说明(函数说明),而制作这些工具也会使用许多材料结构即(函数体),当然一件工具会有命名即(函数名),而当我们使用工具完成后会获得一些效果,我们也可以将这些效果称为(返回值)。当然有工具自然会有工具箱即(类)。 |
二、函数的定义:
定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数说明,函数体,函数的返回值用 return 语句返回。
def 函数名(参数1,参数2,参数3,......):
"""
函数说明
"""
函数体
return 返回值
例如:
#定义一个获取平方值的函数
def calc(x):
"""
:param x: 输入数字
:return: 获取该数字的返回值
"""
res =x**2
return res #获取返回值
res = calc(10)
print(res)
注意:函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,即函数内return后面代码将无效,并将结果返回。如果没有return语句的函数,很多时候将其称为过程,但其实默认返回None。
函数的定义通常类似于变量的定义,定义一个函数只给了函数一个名称,指定了函数里包含的参数,和代码块结构。与变量类似,函数的定义也相当于将代码块以一种特定的方式存储在内存中,只有当调用的时候才会执行,而当我们打印函数名时,其实打印的是内存地址;当打印函数名加括号时,则是返回值。例:
def greater(name):
print("hello world,%s !"%name)
return name greater("amanda") #调用函数,执行函数
print(greater) #打印函数地址
print(greater("amanda")) #调用函数,并且获取返回值 #输出为:
#hello world,amanda !
#<function greater at 0x00000241C37A3E18>
#hello world,amanda !
#amanda
当调用函数时,需传入指定类型的参数,才会执行函数体中的代码块。
三、函数的参数:
3.1 形参和实参
形参即形式参数,函数完成其工作时所需的一项信息。形参不占用内存空间,只有在被调用时才会占用内存空间,调用完了即被释放。
实参即实际参数,调用函数时传给函数的信息。例如:
#形参和实参
def greater(name): #name即为形参
print("hello world,%s !"%name)
return name greater("amanda") #Amanda即为实参
上述而言:在调用函数并传入参数即greater("Amanda"),将实参"Amanda"传递给函数greater(),这个值就被存储在形参name中。
3.2 位置参数和关键字参数
位置参数--> 在调用函数时,Python必须将每个实参都关联到函数定义的一个形参中,最简单的关联方式就是基于实参的顺序,这种方式即为位置实参。
关键字参数 --> 传递给函数的是键值对。由于在实参中的将名称和值关联起来,所以在传入时无需考虑顺序。
#位置参数,一一对应,不可多也不可少
def introduction(name,age,hobby):
intro ="My name is %s,I'm %d years old,my hobby is %s."%(name,age,hobby)
print(intro) introduction("Amanda",23,"eating")
位置参数
#关键字参数,无需一一对应,但也不可多不可少
def introduction(name,age,hobby):
intro ="My name is %s,I'm %d years old,my hobby is %s."%(name,age,hobby)
print(intro) introduction(age=22,name="little-five",hobby="dancing")
关键字参数
但位置参数和关键字参数混合使用时:
1、位置参数必须写在关键字参数的左边
2、同一个参数不能两次或者多次传值,只能传一次
#位置参数和关键字参数混合使用
def introduction(name,age,hobby):
intro ="My name is %s,I'm %d years old,my hobby is %s."%(name,age,hobby)
print(intro) introduction("Amanda",age="",hobby="eating") #位置参数必须写在关键字参数左边
#introduction(name="Amanda",23,hobby="eating")
#同一个参数传值只能一次
#introduction("Amanda",23,age="eating")
混合使用
注:在没有参数组的情况下,传入的值必须与形参的数量一致。
3.2 默认参数
定义函数时我们可以给参数传递默认值,当调用函数时没有传递该参数值时使用默认参数值。带默认值的参数称为默认参数,而无默认值的参数为必需参数,调用函数时必需参数必填,默认参数选填。例如:
#默认参数
def introduction(name,age,hobby="runing"):
intro ="My name is %s,I'm %d years old,my hobby is %s."%(name,age,hobby)
print(intro) #当不给默认参数传值时,默认使用默认参数值
introduction("Amanda",23)
#而给默认参数传值时,则覆盖
introduction("Amanda",age=23,hobby="eating")
3.4 参数组
*args -->传入的多余的位置参数,被args接收。即当要想传入多于形参的实参,并且以位置参数的方式传入,多于的参数其以元组的形式接收。
def calc(x,y,*args):
res =x+y
# print(x,y)
print(x,y,args)#*args-->多于的参数,位置参数传入,以元组的形式接收
return res
calc(1,2,7,8,6)
calc(2,3,{"name":"alex"}) #即使传入字典,字典当成整体也会以元组的方式被接收
calc(3,4,["alex","James"],"hello world")
calc(3,4,*["alex","James"]) #相当于该列表遍历,逐个添加至列表并且转为元组
calc(3,4,*"alex") #输出为:
#1 2 (7, 8, 6)
#2 3 ({'name': 'alex'},)
#3 4 (['alex', 'James'], 'hello world')
#3 4 ('alex', 'James')
#3 4 ('a', 'l', 'e', 'x')
*args
**kwargs -->传入的多余的关键字参数,被kwargs接收。即要想传入多于形参的实参,并且以关键字参数的形式传入,多于的参数其以字典的形式接收
#
def calc(x,y,**kwargs):
res =x+y
#print(x,y)
print(x,y,kwargs)#**kwargs-->多于的参数,位置参数传入,以字典的形式接收
return res
calc(x=1,y=3,name="alex")
calc(1,2,**{"name":"Amanda"}) #输出为:
#1 3 {'name': 'alex'}
#1 2 {'name': 'Amanda'}
**kwargs
当在函数值定义参数时,同时定义*args、**kwargs时,可以传入任何参数。多余的位置参数,传入函数,以元组的方式被存储在*args中;而多余的关键字参数,传入函数,以字典的方式被存储在**kwargs中。
def calc(x,y,*args,**kwargs):
res =x+y
print(x,y,args,kwargs)#*args,**kwargs-->可以传入任何参数
return res
calc(1,23,"",["Amanda","little-five"],greater="hello world") #输出为:
#1 23 ('222', ['Amanda', 'little-five']) {'greater': 'hello world'}
四、函数的作用域
这里我们需要简单的了解以下关于变量的作用域有哪几种?
L:local,局部作用域,即函数中定义的变量。 E: enclosing,嵌套父级函数的局部作用域,即包含此函数的上级的局部作用域,但不是全局的; G: global,全局变量,就是模块级别定义的变量。 B: built-in,系统固定模块里面的变量,比如 int,bytearray等。 搜索变量的优先级顺序依次为: 局部作用域 >外层作用域 >当前模块中的全局作用域 > python内置作用域,也就是 LEGB |
通过以下代码或许我们可以更好的理解这四种作用域之间的关系:
#!/usr/bin/env python
# -*- coding:utf-8 -*- x =int(1) #python内置作用域---->B
y =2 #当前模块中的全局变量--->G
def outfunc():
outpara = 3 #外层作用域 --->E
def infunc():
inpara =4 #局部作用域 --->L
print(inpara)
infunc()
outfunc()
同时我们需要知道的是,函数中变量的作用域只与函数的声明有关,而与函数的调用位置无关。通过下面这个例子我们可以知晓:
#函数名-->函数内存地址;函数名()-->执行函数,并且获取返回值
name ="zhangsan"
def foo():
name ="lisi"
def bar():
name = "wangwu"
def mitt():
print(name)
return mitt
return bar foo()()()
#相当于---------------
# bar =foo() #执行foo函数,并且获取bar函数内存地址,并且赋值给bar变量
# mitt =bar() #bar内存地址加括号->执行bar函数,并且获取mitt内存地址
# mitt() #mitt内存地址+括号-->执行mitt函数 #输出结果为:wangwu 而不是zhangsan
这个结果为wangwu而不是zhangsan,则说明函数中变量的作用域只有函数的声明有关,而与函数的调用位置无关。否则,输出肯定为->zhangsan,因为若简单的调用mitt()其变量为 name=”zhangsan“,则打印的为zhangsan。
五、全局变量和局部变量:
在函数外,一段代码最开始所赋值的变量,其可以被多个函数所调用,其作用域为全局作用域,则称为全局变量。
在函数内定义的变量名,只能在该函数内部引用,不能在函数外部引用这个变量名,其作用域为局部作用域,则称为局部变量。例如:
name ="Amanda" #全局变量
def foo():
name ="zhangsan"
print(name)
def bar():
name ="lisi" #局部变量
print(name)
bar()
print(name)
foo() #输出结果:
# Amanda
# zhangsan
# lisi
全局变量和局部变量
global -->若想在函数内部修改全局变量,则需要使用global关键
#注:global必须写在全局变量修改前
name ="Amanda" #全局变量
def foo():
name ="zhangsan"
print(name)
def bar():
global name #修改的为全局变量
name ="lisi" #局部变量
print(name)
bar()
print(name) #函数没有执行前,故打印的还是原局部变量name
foo() #执行函数
print(name) #函数执行后,修改了全局变量为name =lisi
nonlocal -->若子函数内想修改父级函数的变量,则需要使用 nonlocal 键字
name ="Amanda" #全局变量
def foo():
name ="zhangsan"
print(name)
def bar():
nonlocal name
name ="lisi" #局部变量
print(name)
bar()
print(name) #由于函数没有调用前,函数没有执行,故打印的还是Amanda
foo() #函数执行
print(name) #函数执行后,由于nonlocal关键字,修改的仅是父级的变量name
注:无论是global还是nonlocal,都必须写在变量的修改的前面。否则会报错。
第五篇:Python函数基础篇的更多相关文章
- Python—函数基础篇
https://www.cnblogs.com/littlefivebolg/p/9017449.html Python 解释器的内置函数 内置函数 作用 实例 abs() 返回数字的绝对值. abs ...
- python函数-基础篇
函数 为什么要用函数?1.减少代码冗余2.增加代码可读性 函数的定义及使用 def info(): # 这里我们定义一个打印个人信息的函数 name = "xiaoming" ag ...
- 第六篇:Python函数进阶篇
在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点: 一.Python的迭代器 ...
- 《转》Python学习(17)-python函数基础部分
http://www.cnblogs.com/BeginMan/p/3171977.html 一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/arch ...
- 孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备
孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天本来应当继续学习Python的数据库操作,但根据过去我自 ...
- 第四篇.python的基础
目录 第四篇.python基础01 1. 变量 2. 常量 3. python变量内存管理 4. 变量的三个特征 5. 花式赋值 6. 注释 7. 数据类型基础 8. 数字类型 9. 字符串类型 10 ...
- python+selenium基础篇,切入切出frame
1.首先制作一个html的文件,代码如下 <!DOCTYPE html> <html> <head> <title>Frame_test</tit ...
- Python面试基础篇
1. 为什什么学习Python? Life is short, You need Python 2. 通过什什么途径学习的Python? pass 3. Python和Java.PHP.C.C#.C+ ...
- [python 函数学习篇]默认参数
python函数: 默认参数: retries= 这种形式 def ask_ok(prompt, retries=, complaint='Yes or no, please!'): while Tr ...
随机推荐
- requests---参数关联
在做接口测试的过程中,我们经常会遇到参数关联,也就是我们经常所说的上一个接口返回是下一个接口的请求 参数关联 在应用业务接口中,完成一个业务功能时,有时候一个接口可能不满足业务的整个流程逻辑,需要多个 ...
- 非ssl给163发邮件,报错,无解ing
#给163发送邮件import smtplibfrom email.mime.text import MIMETextnam='15527721040@163.com'send='1552772104 ...
- c# 第23节 外部方法
本节内容: 1:外部方法是什么 2:外部方法的实现 1:外部方法是什么 2:外部方法的实现 样式: 实现方式:很少 用自己多加练习把
- 如何在Windows系统上基于Sublime搭建Python的编译环境
刚刚接触到Python,直接在计算机上编译时不能正确的运行,所以将一些有关编译环境调试的知识总结了一下. 环境搭建: Python在 windows系统上编译的时候可能会出现一些编译无法运行的情况,我 ...
- [C8] 聚类(Clustering)
聚类(Clustering) 非监督学习:简介(Unsupervised Learning: Introduction) 本章节介绍聚类算法,这是我们学习的第一个非监督学习算法--学习无标签数据,而不 ...
- template指针小测试
测试结论: 1 函数指针 -- 使用形参固定的一系列函数作为某个函数的形参 -- callback机制 2 模板指针 -- 使用形参可变的一系列函数作为某个函数的形参 -- 3 typename -- ...
- 题解:swj社会摇基础第一课
题目链接 思路:dp,f[i]表示构成i所需要的最小步数 //swj么么哒 #include<bits/stdc++.h> using namespace std; int n; cons ...
- php 学习笔记之关于时区的那点事
科普一下什么是时区 众所周知,地球绕着太阳转的同时也会自转,因此同一时刻不同地区所接收到太阳照射的情况不同,所以有的地区是日出,有的地区是日落,还有的地区可能是黑夜. 既然地球上的不同地区时间不同,那 ...
- [日常] 用vim的时候发现的不是很小的bug...
前一天晚上的时候不知道搞啥了...第二天早上起来开 gnome-system-monitor 的时候发现CPU占用好像不太对头 (一直有个核是 \(100\%\)), 转到进程的时候发现使用最高的居然 ...
- vue自定义事件---拖拽
margin布局拖拽 Vue.directive('drag', { bind(el, binding, vnode, oldVnode) { const dialogHeaderEl = el.qu ...