Python3函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.

函数能提高应用的模块性,和代码的重复利用率。Python提供了许多内建函数,比如print()。我们可以直接调用,要调用一个函数,需要知道函数的名称和参数,可以直接从Python的官方网站查看文档:

https://docs.python.org/3/library/functions.html

也可以在交互式命令通过help(print)查看print函数的帮助信息

但你也可以自己创建函数,这被叫做用户自定义函数。

定义函数

  • 你可以定义一个自己想要功能的函数,以下是简单的规则:
# 1. 函数代码块以def关键词开头,后接函数标识符名称和圆括号()
# 2. 任何传入参数和自定义变量必须放在圆括号中间,圆括号之间可以用于定义参数.
# 3. 函数的第一行语句可以选择性地使用文档字符串用于存放函数说明
# 4. 函数内容以冒号起始,并且缩进。
# 5. reture[表达式]结束函数,选择性地返回一个值调用方,不带表达式的return相当于返回None. # 函数: 以功能(完成一件事)为导向,登录,注册,len,一个函数就是一个功能
# 随调随用
#
# 函数作用
# 1. 减少代码重复性.
# 2. 使代码可读性更好.

语法:

Python定义函数使用def关键字,一般格式如下:

def  函数名 (参数列表):
函数体 # 默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的. # def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"
# def 是固定的,不能变,也就是定义函数的关键字
# 函数名: 函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并且要具有可描述性

Example1

我们使用函数来输出"Hello World!"

def hello():
print('hello world')
hello() # hello world

更复杂点的应用,函数中带上参数变量

# 求元素多少个,长度,传统方法low
li1 = [1, 2, 3, 4, 5]
count = 0
for i in li1:
count += 1
print(count) # 函数实现求列表多少个元素
def my_len(l):
count = 0
for i in l:
count += 1
print(count)
my_len(li1) def area(width, height):
return width * height def print_welcom(name):
print("Welcome",name) print_welcom("You-Men")
w = 4
h = 5
print("width = ",w,"height = ",h,"area =",area(w,h))

函数调用

Example2

定义一个函数: 给了函数一个名称,指定了函数包含的参数和代码块结构.

这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python命令提示符执行.

如下实例调用了printme()函数.

# 当函数遇到函数名+ (),函数才会执行

def printme(str):
print(str)
return printme("我要调用自定义函数")

函数的返回值

一个函数就是封装一个功能,这个功能一般都会有一个最终结果的,比如你写一个登录函数,最终登录成功与否是不是需要返回你一个结果?还有咱们是不是都用过len这个函数,他是获取一个对象的元素的总个数,最终肯定会返回一个元素个数这样的结果:

那么这个返回值如何设置呢?这就得用到python中的一个关键字:return

def date():
print("拿出手机")
print("打开陌陌")
print('左滑一下')
print('右滑一下')
print("找个漂亮的妹子")
return
print("问她,约不约啊!")
print("ok 走起") # 总结
# 1. 函数中遇到return,此函数结束,不再继续执行 # 2. return会给函数的执行则返回值
# 如果return后面什么都不写,或者函数中没有return,则返回的结果是None
# 如果return后面写了一个值,返回给调用者这个值
# 如果返回多个值,是以tuple(元组)的形式返回的,调用者可以直接使用元组的

函数参数传递

上面有说道函数结构,函数执行,函数返回值,对函数有一个初步的了解,接下来就是函数的参数.

函数是以功能为导向的,上面我们写的函数里面代码都是写死的,也就是说,函数里面更改很麻烦,所以可以通过传参解决这种写死代码.

在Python中,类型属于对象,变量是没有类型的

a=[1,2,3]
a="YouMen"

以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。

可更改(mutable)与不可更改(immutable)对象

在python中,strings,tuples,和numbers是不可更改的对象,而list,dict等则是可以修改的对象.

  • 不可变类型: 变量a=5后再赋值a=10,这里实际是新生成一个int值对象10,再让a指向他,而5被丢弃,不是改变a的值,相当于新生成了a.

  • 可变类型: 变量赋值la=[1,2,3,4]后再赋值la[2]5则是将list la的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了.

Python函数的参数传递

不可变类型: 类似C++的值传递,如整数、字符串、元组,如fun(a),传递的只是a的值,没有影响a对象本身,比如fun(a)内部修改a的值,只是修改另一个赋值的对象,不会影响a本身.

可变类型: 类似C++的引用传递,如,列表,字典。如fun(la),则是将la真正的传过去,修改后fun外部的la也会受到影响.

Python中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说不可变对象和传可变对象

Python传不可变对象实例

def ChangeInt(a):
a = 10
b = 2
ChangeInt(b)
print(b) # 上面实例运行结果为: # 实例中有int对象2,指向他的变量是b,在传递ChangeInt函数时,按传值的方式复制了变量b,a和b都指向了同一个Int对象,在a=10时,则新生成一个int值对象10,并让a指向他

传可变对象实例

可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了,比如

# 可写函数说明  

def changeme( mylist ):
"修改传入的列表"
mylist.append([1,2,3,4])
print ("函数内取值: ", mylist)
return # 调用changeme函数 mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist) # 传入函数的和末尾添加新内容的对象是同一个引用,故输出结果如下: 函数内取值: [10, 20, 30, [1, 2, 3, 4]]
函数外取值: [10, 20, 30, [1, 2, 3, 4]]

参数

以下是调用函数的可使用的正式参数类型:

  • 必需参数
  • 关键字参数
  • 默认参数
  • 不定长参数
必需参数

必须参数以正确的顺序传入函数,调用时的数量必须和声明时的一样

调用printme()函数,你必须传入一个参数,不然会出现语法错误

# 可写函数说明  

def printme(str):
"打印任何传入的字符串"
print(str)
# return # 不加参数会报错
printme('Hello')
关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值.

使用关键字参数允许函数调用时的顺序和声明时不一样,因为Python解释器能够用参数名匹配参数值

以下实例在函数printme()调用时使用参数名

# 写一个函数,只接受两个数字,int参数,函数功能实现将较大的数返回

def sum(a,b):
if a > b:
return a
elif a == b:
return "相等"
else:
return b print(sum(2,2)) # 实参角度
# 1. 位置参数,按照顺序,一一对应
# 2. 关键字参数,一一对应
# 3. 混合参数,位置参数一定要在关键字参数的前面

以下实例演示了函数参数的使用不需要指定顺序

def printfo(name,age):
print("名字",name)
print("年龄",age)
return printfo(age=10,name='youmen') # 名字 youmen
# 年龄 10
默认参数

调用函数时,如果没有传递参数,则会使用默认参数,以下实例如果没有传入age参数,则使用默认值

# 设置意义在于普遍经常使用的
# 可写函数说明 def printfo(name,age=15):
"打印任何传入的字符串"
print("名字",name)
print("年龄",age)
return
printfo(age=50,name='YouMen')
print("--------------")
printfo(name='Flying') # 名字 YouMen
# 年龄 50
--------------
# 名字 Flying
# 年龄 15
不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下:

# 可写函数说明
def printfo(arg1,*vartuple):
"打印任何传入的参数"
print("输出:")
print(arg1)
print(vartuple) # 调用printfo函数
printfo(30,40,50,60) # 输出:
# 30
# (40, 50, 60)

还有一种就是参数带两个星号**基本语法如下:

# 可写函数说明
def printfo(arg1,**vardict):
print("输出:")
print(arg1)
print(vardict) printfo(1234,a=2,b=3) # 加了两个星号**就会以字典的形式导入
# 输出:
# 1234
# {'a': 2, 'b': 3}

如果是单独出现*后的参数必须用关键字传入 :

# 可写函数说明
def printfo(a,b,*,c):
print("输出:")
print(a)
print(b)
print(c)
printfo(1,2,c=3) # 如果是printfo(1,2,3)会报错 # 输出:
# 1
# 2
# 3
万能参数

(*args)

# 万能参数
# *args,约定俗称,
# * 函数定义时,*代表聚合,他将所有的位置参数聚合成一个元祖,赋值给args # 写一个函数: 计算你传入函数的所有数字的和
def func(*args):
count = 0
for i in args:
count += i
return count print(func(1,2,3,4,5,6,7))

( kwargs)

# **kwargs
# 函数定义时,**将所有的关键字参数聚合到一个字典中,将这个字典赋值给了kwargs
def func(**kwargs):
print(kwargs) func(name='youmen',age=18,sex='boy') # {'name': 'youmen', 'age': 18, 'sex': 'boy'} def func(a,b,*args,sex='男',c,**kwargs):
print(a,b)
print(sex)
print(args)
print(c)
print(kwargs)
func(1,2,3,4,5,6,sex='女',c=60) # 1 2
# 女
# (3, 4, 5, 6)
# 60
# {}

匿名函数

Python使用lambda来创建匿名函数

所谓匿名,意即不再使用def语句这样标准的形式定义一个函数.

  • lamdba只是一个表达式,函数体比def简单很多
  • lamdba的主题是一个表达式,而不是一个代码块,仅仅能在lambda表达式封装有限的逻辑进去.
  • lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数
  • 虽然lambda函数看起来只能写一行,却不能同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率

语法

# lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,....argn]]:expression
# 如下实例: # 可写函数说明
sum = lambda arg1,arg2 : arg1 + arg2 # 调用sum函数
print("相加后的值为:",sum(10,20))
print("相加后的值为:",sum(20,20)) 相加后的值为: 30
相加后的值为: 40

return语句

return [表达式]语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值,以下实例演示了 return 语句的用法:

# 可写函数说明
def sum(arg1,arg2):
"返回2个参数的和"
total = arg1 + arg2
print("函数内:",total)
return total # 调用sum函数
total = sum(10,20)
print("函数外:",total) 函数内: 30
函数外: 30

强制位置参数

  • Python3.8新更加了一个函数形参语法/用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f) # 以下使用方法是正确的:
f(10, 20, 30, d=40, e=50, f=60) 以下使用方法会发生错误: f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式

函数名称空间,作用域

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

我们首先回忆一下Python代码运行的时候遇到函数是怎么做的,从Python解释器开始执行之后,就在内存中开辟里一个空间,每当遇到一个变量的时候,就把变量名和值之间对应的关系记录下来,但是当遇到函数定义的时候,解释器只是象征性的将函数名读如内存,表示知道这个函数存在了,至于函数内部的变量和逻辑,解释器根本不关心。

等执行到函数调用的时候,Python解释器会再开辟一块内存来储存这个函数里面的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量回储存在新开辟出来的内存中,函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

我们给这个‘存放名字与值的关系’的空间起了一个名字-------命名空间。

代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间;

在函数的运行中开辟的临时空间叫做局部命名空间也叫作临时名称空间

在py文件中,存放变量与值关系的一个空间叫做全局名称空间,而当执行一个函数时,内存中会临时开辟一个空间,临时存放函数中的变量与值的关系,这个叫做临时名称空间,或者局部名称空间.

python中还有一个空间叫做内置名称空间: 内置名称空间存放的就是一些内置函数等拿来即用的特殊的变量: input,print,list等等.

# 1. 全局命名空间  --->  我们直接在py文件中,函数外声明的变量都属于全局命名空间

# 2. 局部命名空间  ---> 在函数中声明的变量会存放在局部命名空间

# 3. 内置命名空间  ---> 存放python解释器为我们提供的名字,list,tuple,str,int这些都是内置命名空间.
加载顺序

所谓的加载顺序,就是这三个空间加载到内存的先后顺序,也就是这三个空间在内存中创建的先后顺序,你想想他们能是同时创建么?肯定不是的,那么谁先谁后呢?我们捋顺一下:在启动python解释器之后,即使没有创建任何的变量或者函数,还是会有一些函数直接可以用的比如abs(-1),max(1,3)等等,在启动Python解释器的时候,就已经导入到内存当中供我们使用,所以肯定是先加载内置名称空间,然后就开始从文件的最上面向下一行一行执行,此时如果遇到了初始化变量,就会创建全局名称空间,将这些对应关系存放进去,然后遇到了函数执行时,在内存中临时开辟一个空间,加载函数中的一些变量等等。所以这三个空间的加载顺序为:内置命名空间(程序运行伊始加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载。

取值顺序

取值顺序就是引用一个变量,先从哪一个空间开始引用,这个有一个关键点: 从那个空间开始引用这个变量,我们分别举例说明:

# 如果你在全局名称空间引用一个变量,先从局部名称空间引用,全局名, 如果没有,才会向内置名称空间引用

# sum=666
print(sum) def func():
# sum = 555
print(sum)
func() name='flying'
def func():
# name='youmen'
print(name)
func() # 取值顺序(就近原则)
# 从(局部变量找)局部名称空间 ---> 全局名称空间 ---> 内置名称名称空间
作用域

作用域也就是作用范围, 控制生效范围来看全局作用域和局部作用域

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

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

作用域命名空间

# 1. 全局作用域:  全局命名空间 + 内置命名空间
# 2. 局部作用域: 局部命名空间 def func1():
print('in fun1')
print(3) def fun2():
print('in fun2')
print(4) func1()
print(1) fun2()
print(2) # in fun1
# 3
# 1
# in fun2
# 4
# 2 print("#############################")
def fun2():
print(2)
def func3():
print(6)
print(4)
func3()
print(8)
print(8)
fun2()

函数名

func()
# 1. 函数名指向的是函数的内存地址.
# 函数名 + ()就可以执行函数 # 2. 函数名就是一个变量,既然是变量就可以赋值运算 # 3. 函数名可以作为容器数据类型的元素
def fun1():
print("in fun1") def fun2():
print("in fun2") def fun3():
print("in fun3") li1 = [fun1,fun2,fun3]
for i in li1:
i() # 4. 函数名可以作为函数的参数 def func():
print('in func') def func1(x): # x = func
print('in func1')
return x ret = func1(func)
ret()
关键字(Global)
# 当我们程序中遇到局部作用域去改变全局作用域的一些变量的需求,可以使用关键字global:
# global第一个功能: 在局部作用域中可以更改全局作用域的变量. a = 1
def func():
print(a)
func()
# a = 1
def func():
global a
a += 1
print(a)
func()

07 . Python3函数的更多相关文章

  1. python3函数

    一.python3函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.可以自己创建函数,这被叫做用户自定义函数. 1.定义函数规则 函 ...

  2. python015 Python3 函数

    Python3 函数函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...

  3. Python3函数中特殊形参的使用:*、*args、**kwargs

    Python3函数中特殊形参的使用:*.*args.**kwargs ==用法1:不定长参数== 当函数需要的参数数量不确定的时候,可以使用*args 和 **kwargs , 所有的位置参数保存在* ...

  4. (07)-Python3之--函数

    1.定义 函数:实现了某一特定功能.    可以重复使用. 例如: len()   功能:获取长度.input()   功能: 控制台输入print()   功能:输出 语法: def 函数名称(参数 ...

  5. 汉诺塔python3函数编写和过程分析

    !/usr/bin/env python3 -- coding: utf-8 -- 利用递归函数计算阶乘 N! = 1 * 2 * 3 * ... * N def fact(n): if n == 1 ...

  6. Python3 函数注解

    Python3提供一种语法,用于为函数声明中的参数和返回值附加元数据.下面的例子是注解后的版本,特点在第一行: 1 def clip(text : str, max_len : 'int > 0 ...

  7. 5 Python3 函数进阶&迭代器与生成器

    1.函数进阶 1.1.名称空间 又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的 ...

  8. Python3 函数作用域

    一 LEGB 什么是LEGB? L:local 函数内部作用域 E:enclosing 函数内部与内嵌函数之间 G:global 全局作用域 B:build-in 内置作用域 顺序是什么? 跟名字一样 ...

  9. python系列十:python3函数

    #!/usr/bin/python #-*-coding:gbk-*- '''函数的简单规则:    函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ().    任何传入参数和自变量必 ...

随机推荐

  1. Android 开发技术周报 Issue#278

    新闻 Pixel 4a渲染图曝光:或能成新款iPhone SE有力竞争者 Google Play商店为预注册的游戏和应用提供自动安装功能 Android最强单摄Pixel 4a样张曝光:1200万像素 ...

  2. 蒲公英 · JELLY技术周刊 Vol.05: Rust & Electron 的高性能实践 -- Finda

    登高远眺 天高地迥,觉宇宙之无穷 基础技术 使用 JavaScript 框架的代价 作者从 JavaScript 下载时间.解析时间.执行时间.内存占用四个角度评测了 jQuery.Angular.R ...

  3. 一文带你深入了解 Lambda 表达式和方法引用

    前言 尽管目前很多公司已经使用 Java8 作为项目开发语言,但是仍然有一部分开发者只是将其设置到 pom 文件中,并未真正开始使用.而项目中如果有8新特性的写法,例如λ表达式.也只是 Idea Al ...

  4. 揭露.net培训结构软谋收钱踢学员的套路

    本人以下文章全部真实,希望管理员能通过,给更多的.net学者一个警示,避免更多的.neter掉入泥坑. 本人小码农一枚,主要做.net方向,苦于进步无门,各种资料收集渠道受限,最后狠心花一个月工资报名 ...

  5. C. Two Arrays(思维DP或组合数学)

    \(首先很容易想到一个O(n^4m)的DP\) \(设dp\ [i]\ [j]\ [q]\ 为长度i,a数组以j结尾,b数组以q结尾(q>=j)\) for(int i=1;i<=n;i+ ...

  6. 【Flink】使用之前,先简单了解一下Flink吧!

    目录 Flink简单介绍 概述 无边界数据流和有边界数据流 技术栈核心组成 架构体系 重要角色 Flink与Spark架构概念转换 Flink简单介绍 概述    在使用Flink之前,我们需要大概知 ...

  7. 用PHP获取网页上的信息相对于xpath效率低点

    用php实现对网页的抓取,及信息的收集,其实就是爬数据,具体实现步骤如下,首先应引入两个文件curl_html_get.php和save_file.php文件,两个文件具体代码是这样的curl_htm ...

  8. 【基础】excel如何根据数据内容显示不同颜色。

    需求: 店柜完成率排名相比上阶段升降,升显示绿色“↑“,降显示红色“↓”,持平显示黑色“-”. 步骤: 第一步 先计算两次排名的差值(本次排名-上次排名). 第二步 对差值列设置单元格格式,设置格式如 ...

  9. STM32 外部中断详解(原理+配置代码)

    本文介绍了STM32基于标准外设库的外部中断配置,以及基于参考手册如何更加寄存器配置外部中断 文章目录 1 前言 2 STM32的外部中断 3 中断服务函数的映射关系 4 外部中断的配置 5 寄存器的 ...

  10. scrapy实现数据持久化、数据库连接、图片文件下载及settings.py配置

    数据持久化的两种方式:(1)基于终端指令的持久化存储:(2)基于管道的持久化存储 基于终端指令的持久化存储 在爬虫文件的parse方法中必须要return可迭代对象类型(通常为列表或字典等)的返回值, ...