本篇介绍什么是函数、函数的特性、函数的定义、函数的调用、以及函数的参数、以及关于全局变量和局部变量的使用等等。

一、什么是函数:

  函数是最基本的一种代码抽象方式,为了实现某种特定的功能而组织的带名字的代码块。

  那为什么要使用函数呢?

    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函数基础篇的更多相关文章

  1. Python—函数基础篇

    https://www.cnblogs.com/littlefivebolg/p/9017449.html Python 解释器的内置函数 内置函数 作用 实例 abs() 返回数字的绝对值. abs ...

  2. python函数-基础篇

    函数 为什么要用函数?1.减少代码冗余2.增加代码可读性 函数的定义及使用 def info(): # 这里我们定义一个打印个人信息的函数 name = "xiaoming" ag ...

  3. 第六篇:Python函数进阶篇

    在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点:  一.Python的迭代器 ...

  4. 《转》Python学习(17)-python函数基础部分

    http://www.cnblogs.com/BeginMan/p/3171977.html 一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/arch ...

  5. 孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备

     孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天本来应当继续学习Python的数据库操作,但根据过去我自 ...

  6. 第四篇.python的基础

    目录 第四篇.python基础01 1. 变量 2. 常量 3. python变量内存管理 4. 变量的三个特征 5. 花式赋值 6. 注释 7. 数据类型基础 8. 数字类型 9. 字符串类型 10 ...

  7. python+selenium基础篇,切入切出frame

    1.首先制作一个html的文件,代码如下 <!DOCTYPE html> <html> <head> <title>Frame_test</tit ...

  8. Python面试基础篇

    1. 为什什么学习Python? Life is short, You need Python 2. 通过什什么途径学习的Python? pass 3. Python和Java.PHP.C.C#.C+ ...

  9. [python 函数学习篇]默认参数

    python函数: 默认参数: retries= 这种形式 def ask_ok(prompt, retries=, complaint='Yes or no, please!'): while Tr ...

随机推荐

  1. XGBoost、LightGBM参数讲解及实战

    本文链接:https://blog.csdn.net/linxid/article/details/80785131XGBoost一.API详解xgboost.XGBClassifier1.1 参数1 ...

  2. itest(爱测试) 3.3.7 发布,开源BUG 跟踪管理& 敏捷测试管理软件

    v3.3.7 下载地址 :itest下载 itest 简介:查看简介 V3.3.7 增加了 5个功能增强,和8个BUG修复 ,详情如下所述. 5个功能增强 :(1)任务看板中,除了显示任务外,增加测试 ...

  3. c语言程序设计第1章

    开始记录自己学习c语言的过程,选用的教材是浙江大学何钦铭.颜晖编写的<c语言程序设计>(第3版). 一.第一个程序 /*求阶乘问题.输入一个正整数n,输出n!*/ #include< ...

  4. 文件名工具类 MoFileNameUtil

    文件名工具类 MoFileNameUtil MoFileNameUtil public class MoFileNameUtil { //不包含点号 public static String getF ...

  5. 移动端(手机端)页面自适应解决方案1(rem布局)---750设计稿

    设计稿尺寸为750 * 1340.结合网易.淘宝移动端首页html元素上的动态font-size属性.设计稿尺寸.前端与设计之间协作流程一般分为下面两种: 网易做法: 页面开头处引入下面这段代码,用于 ...

  6. Codeforces Round #597 (Div. 2) C. Constanze's Machine dp

    C. Constanze's Machine Constanze is the smartest girl in her village but she has bad eyesight. One d ...

  7. CSP-J&S2019第一轮认证游记

    Day-0 晚上和高一大佬BH聊了聊,感觉大佬第一次参加比赛毕竟还是有点慌QAQ,毕竟我这么菜的人都没慌过. 做了一套模拟题,用45分钟瞎打的提高组卷子得了62分,还不错,正式比赛用2个小时好好答的话 ...

  8. springboot2.0 management.security.enabled无效

    在1.5.x版本中通过management.security.enabled=false来暴露所有端点 在使用springcloud的时候,如果基于springboot2的版本的配置中心,无法使用SV ...

  9. iOS Workflow 分享 - Debug Action

    有时候我们想要知道别人的 app 在调用 Share Extension 时提供了什么类型的数据以及具体数据是什么,我们可以自己在 Xcode 里面写个 app 去接收别人 app 的数据,但我们也可 ...

  10. webpack打包教程(一)常用loader详解

    1.打包图片 // { // test: /\.(png|jpe?g|gif)$/i, // use: [{ // loader: 'file-loader', // options: { // na ...