Python函数

函数的作用:对功能进行封装,减少重复代码,方便维护,流程清晰明了,易于理解。

函数的结构:
      def 函数名():
            函数体
            return语句

函数的返回值:

  • 可以用于终止函数的运行,也可以返回一个值给调用者。
  • 如果函数不写返回值默认返回一个None。
  • 函数return可以返回任意数据类型。
  • 如果return多个值则返回的数据类型是元组。
  • 如果return一个数据,返回值是原数据类型。.

return返回一个值,如下:

def fun():
return 1 # return 数字1
ret = fun()
print(type(ret),ret) 打印内容如下:
<class 'int'> 1

return返回多个值,如下:

def fun():
  return 1,2,3,4 # return多个值
ret = fun()
print(type(ret),ret) # 打印内容如下:
<class 'tuple'> (1, 2, 3, 4)

函数的参数:

形参:分为位置参数、默认参数、混合参数三种。

实参:分为位置参数、关键字参数、混合参数三种。

传参:指从实参到形参的传递过程。.

参数的顺序: 位置参数 > 默认参数(关键字参数),在默认参数前边写位置参数。

位置传参。如下:

def max_num(num1,num2):   # 返回最大的数字
if num1 > num2:
return num1
else:
return num2
ret = max_num(10,20)
print(ret) 打印内容如下:
20

默认参数,就是如果我们不传参数,函数执行形参中的默认参数。如下:

def max_num(num1=0,num2=20):  # 默认参数
if num1 > num2:
return num1
else:
return num2
ret = max_num(num1=10) # 我们只传递num1参数
print(f'最大数是:{ret}')
# 打印内容如下
最大数是:20

混合传参:

# 参数中有位置参数和默认参数的称为混合参数
# 注意:位置参数必须放在默认参数前
def max_num(num1,num2=20): # 混合传参
if num1 > num2:
return num1
else:
return num2
ret = max_num(10)
print(f'最大数是:{ret}')
# 打印内容如下
最大数是:20

关于默认参数需要注意:

def fun(val, list_1=[]):  # 默认参数是可变的数据类型列表
list_1.append(val)
return list_1 list1 = fun(10)
list2 = fun('Hello World',[]) # 给默认参数传递一个空列表
list3 = fun('a')
list4 = fun('b') print("list1 = %s" % list1)
print("list2 = %s" % list2)
print("list3 = %s" % list3)
print("list4 = %s" % list4) # 打印内容如下
list1 = [10, 'a', 'b']
list2 = ['Hello World']
list3 = [10, 'a', 'b']
list4 = [10, 'a', 'b']

通过打印结果可以发现list1、list3、list4的结果是一样的。它们还有个共同点就是在传参的过程中没有填写默认参数,list2的默认参数因为传递了个空列表,所以结果和其它的不一样。

由此可以知道当默认参数是可变的数据类型时,如果不传递默认参数而是直接使用默认的参数时,虽然多次调用了函数,但是函数的默认参数都是引用同一块的内存地址(应该是为了节省内存),当给默认参数传递一个新值时,函数便开辟了一个新的空间给默认参数使用,所以最终list2和其它的值不一样。

函数动态参数

动态参数分为两种:动态位置参数、动态默认参数。

动态位置参数:动态位置参数会接收所有位置参数,所以要想既使用位置参数又使用动态位置参数,一定要将位置参数放在动态位置参数前面。动态位置参数用return返回的是一个元组,动态位置参数约定俗成使用*args。

在定义形参如:def fun1(*args) 我们将*args定义形参的过程称作聚合,也就是将实参中的多个参数进行聚合。

函数传参如:fun1("Hello",123,"World")  我们将传递多个参数的过程称为打散。

下面是错误的示范:

def fun1(*args,buf):   # 动态位置参数在位置参数前,错误
print(buf)
print(args)
return args
fun1("Hello",123,"World") # 打印内容如下:
TypeError: fun1() missing 1 required keyword-only argument: 'buf'

原因在于动态位置参数会接收所有的参数,导致后面的位置参数无法接收参数导致报错。
下面是正确的写法:

def fun1(buf,*args): #位置参数在动态位置参数前面
print(buf)
print(args)
return args
ret = fun1("Hello",123,"World")
print(type(ret)) # 打印内容如下;
Hello
(123, 'World')
<class 'tuple'> # 动态位置参数的返回类型

但是一般如果用动态位置参数,就很少用位置参数了,上面这种情况一般也只是在特殊情况下会用到。从上面的结果可以得出结论:位置参数必须在动态位置参数前。

动态默认参数:会接收所有默认参数,如果形参中有默认参数,默认参数必须放在动态默认参数前面,动态默认参数用return返回一个字典。动态默认参数约定俗成的使用**kwargs。

def fun1(s2="",**kwargs): # 默认参数必须放在动态默认参数前面
print(s2)
print(kwargs)
return kwargs
ret = fun1(s="Hello",num=123,s2="World")
print(type(ret)) #打印内容如下:
World
{'s': 'Hello', 'num': 123}
<class 'dict'> #动态默认参数返回的是一个字典 def fun(*args,**kwargs): # 万能传参
print(args,kwargs)
fun([1,2,3],(3,2,3),**{"电视剧":1,"电影":2}) # 字典需要打散传递给动态默认参数,如果不打散会被动态位置参数给接收了 # 打印内容太如下:
([1, 2, 3], (3, 2, 3)) {'电视剧': 1, '电影': 2}

关于def fun(*args,**kwargs)这是俗称的万能参数,可以接收任意数量的参数。我们将接收参数的过程称为聚合,而聚合的关键点在于*和**。*和**主要是将从实参传过来的多个参数进行聚合。*args将所有位置参数聚合成元组,而**kwargs将所有默认(关键字)参数聚合成字典。还有个需要注意的地方是在传参的过程如func(1,2,3,**{键:值}),在关键字参数字典中的键必须是字符串否则会报错。

总结:

形参的位置顺序:

位置参数 ==>动态位置参数==>默认参数==>动态默认参数

实参的位置顺序:

位置参数 ==>动态位置参数==>关键字参数==>动态关键字参数

名称空间

在python解释器开始执行之后,就会在内存中开辟一个空间,每当遇到一个变量的时候,就把变量名和值之间的关系记录下来,当遇到函数定义的时候,解释器只是把函数名读入内存,表示这个函数存在了,至于函数内部的变量和逻辑,解释器是不关心的。函数只是加载进来,只有当函数被调用和访问的时候,解释器才会根据函数内部声明的变量来进行开辟变量的内部空间,随着函数执行完毕,这些函数内部变量占用的空间也会随着函数执行完毕而被清空。 
命名空间分类:

  • 内置命名空间:存放python解释器为我们提供的名字、list、tuple、str、int这些都是内置命名空间。
  • 全局命名空间:我们直接在py文件中,函数外声明的变量都属于全局命名空间。
  • 局部命名空间:在函数中声明的变量会放在局部命名空间。

加载顺序:

  1. 内置命名空间
  2. 全局命名空间
  3. 局部命名空间(函数被执行的时候)

取值顺序:

  1. 局部命名空间
  2. 全局命名空间
  3. 内置命名空间

作用域:作用域就是作用范围, 按照生效范围来看分为全局作用域和局部作用域。

全局作用域:包含内置命名空间和全局命名空间。在整个文件的任何位置都可以使用(遵循 从上到下逐步执行)。

局部作用域:在函数内部可以使用。

作用域命名空间:

  1. 全局作用域:全局命名空间 + 内置命名空间。
  2. 局部作用域:局部命名空间。

可以使用globals()函数来查看全局作用域中的内容:

num = 10
print(globals()) # 打印全局作用域的内容 # 打印部分内容如下:
'__cached__': None, 'num': 10}

使用locals()函数来查看局部变量:

def fun1():
num = 10
print(locals()) # 打印局部作用域中的内容
fun1() # 打印内容如下:
{'num': 10}

gloabal和nonlocal

gloabal:用于在局部空间内修改全局变量,如果全局变量不存在将创建一个全局变量。只有数字和字符串需要global,list,dic,set不需要global。

# 全局变量
num = 20
list_1 = [1,2,3] def fun1():
global num # 声明全局变量
num = 10 # 修改全局变量,如果不用global声明在函数内部是不能修改全局变量的 global new_num # new_num不存在将创建成全局变量
new_num = 200 # 给全局变量赋值 list_1.append(10) # 可变数据类型不需要使用global fun1() # 调用函数
print(f'num={num}')
print(f'new_num={new_num}')
print(f'list_1={list_1}') # 打印内容如下
num=10
new_num=200
list_1=[1, 2, 3, 10]

注意:在函数内创建全局变量时必须要调用这个函数才能创建全局变量,否则不能创建全局变量。

nonlocal:必须在嵌套函数内,修改离它最近的那一层的局部变量,如果上一级不存在,继续向上一层找,一直到函数的最外层停止查找,找不到会报错。

nonlocal特点:

1、不能修改全局变量。

2、在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

def fun1():
num = 10 # 局部变量
def fun2():
nonlocal num 向上一层查找局部变量num
num = 200 #修改局部变量num
fun2()
print(num) # 打印局部变量num fun1() # 调用函数打印num最终结果 #打印内容如下:
200 # num被修改成了200

下一篇:函数名,闭包,迭代器:https://www.cnblogs.com/caesar-id/p/10311931.html

Python函数(一)之杵臼之交的更多相关文章

  1. python 函数之day3

    一 函数的语法及特性 什么是函数? 定义:函数是一个功能通过一组语句的集合,由名字(函数名)将其封装起来的代码块,要想执行这个函数,只要调用其函数名即可. 特性: 减少重复代码 使程序变的可扩展 使程 ...

  2. Python函数作用域的查找顺序

    函数作用域的LEGB顺序 1.什么是LEGB? L:local 函数内部作用域 E:enclosing 函数内部与内嵌函数之间 G:global 全局作用域 B:build-in 内置作用域 2.它们 ...

  3. Python函数讲解

    Python函数

  4. Python函数信息

    Python函数func的信息可以通过func.func_*和func.func_code来获取 一.先看看它们的应用吧: 1.获取原函数名称: 1 >>> def yes():pa ...

  5. Python函数参数默认值的陷阱和原理深究"

    本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的 本博客已经迁移至: http://cenalulu.github.io/ 本篇博文已经迁移,阅读全文 ...

  6. Python开发【第四章】:Python函数剖析

    一.Python函数剖析 1.函数的调用顺序 #!/usr/bin/env python # -*- coding:utf-8 -*- #-Author-Lian #函数错误的调用方式 def fun ...

  7. Python函数解析

    对于Python的函数,我们需要记住的是: 1. 函数的默认返回值是None. 2. python是一个自上而下逐行解释并执行的语言.因此,函数的定义必须在函数被调用之前.同名的函数,后定义的会覆盖前 ...

  8. Python入门笔记(18):Python函数(1):基础部分

    一.什么是函数.方法.过程 推荐阅读:http://www.cnblogs.com/snandy/archive/2011/08/29/2153871.html 一般程序设计语言包含两种基本的抽象:过 ...

  9. Python函数1

    Python 函数命令的使用 想想我们之前数学中学到的函数,首先我们需要定义一个函数,例如f(x)=x, 当x输入任意数的时候,f(x)都能输出和x相等的数值. 那么在Python中是如何实现的呢? ...

随机推荐

  1. windows下golang实现Kfaka消息发送及kafka环境搭建

    kafka环境搭建: 一.安装配置java-jdk (1)kafka需要java环境,安装java-jdk,下载地址:https://www.oracle.com/technetwork/java/j ...

  2. Spotlight监控Oracle--Spotlight On Oracle安装和使用

    网上找了很久,发现单独Spotlight On Oracle的安装包很少,要么要积分C币的,要么官网要授权的. 应用过程中也没有一个集安装与运用与一体的文档,故汇总相关信息,供参考. Spotligh ...

  3. SQL执行错误#1064---保留字错误

    CREATE TABLE IF NOT EXISTS `change` ( `id` INT NOT NULL AUTO_INCREMENT, `creator` VARCHAR(45) NOT NU ...

  4. iOS——调试工具LLDB学习

    一.前言 LLDB是个开源的内置于XCode的具有REPL(read-eval-print-loop)特征的Debugger,其可以安装C++或者Python插件.在日常的开发和调试过程中给开发人员带 ...

  5. Hecher学生互助平台(团队项目第一次)

    团队项目作业链接:https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2978 一.团队简介 团队名称:Suc ...

  6. Python内置函数(2)——all

    英文文档: all(iterable) Return True if all elements of the iterable are true (or if the iterable is empt ...

  7. BBS论坛(十七)

    17.首页导航条实现和代码抽离 (1)temlates/common/_head.html <meta name="csrf-token" content="{{ ...

  8. 解放双手—Cobbler批量自动化部署多版本系统

    1 Cobbler  介绍 Cobbler 是一个 Linux 服务器安装的服务,可以通过网络启动(PXE)的方式来快速安装.重装物理服务器和虚拟机,同时还可以管理 DHCP,DNS 等.Cobble ...

  9. asp.net core 系列 19 EFCore介绍

    一.概述 目前最新的EF Core版本是3.0,最稳定的EF Core版本是2.2.EF Core 的计划与 .NET Core以及 ASP.NET Core 版本同步.EF Core 是一个 .NE ...

  10. I-think-2

    最近自己的压力的确很大,对自己近期思想情况做一个总结. 本来假期都自己的未来已经做了一个详细的规划:其中近期的目标就是考上一所自己心仪的大学去读研究生,并且自己也选好了大学,作为自己研究生的目标--- ...