一、 函数定义

1、什么是函数
函数就相当于具备某一功能的工具
函数的使用必须遵循一个原则:
先定义
后调用
2、为何要用函数
代码冗余,程序的组织结构不清晰,可读性差
可维护性、扩展性差
3、如何用函数
# 定义函数
# 定义的语法
def 函数名(参数1,参数2,...):
"""文档描述"""
函数体
return 值 def: 定义函数的关键字;
函数名:函数名指向函数内存地址,是对函数体代码的引用。函数的命名应该反映出函数的功能;
括号:括号内定义参数,参数是可有可无的,且无需指定参数的类型;
冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代码;
"""文档描述""": 描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性;
函数体:由语句和表达式组成;
return 值:定义函数的返回值,return是可有可无的。

二、 函数使用的原则:先定义,再调用

1、调用函数
函数的使用分为定义阶段与调用阶段,定义函数时只检测语法,不执行函数体代码,函数名加括号即函数调用,只有调用函数时才会执行函数体代码
定义阶段
函数的使用必须遵循’先定义,后调用’的原则。函数的定义就相当于事先将函数体代码保存起来,然后将内存地址赋值给函数名,
函数名就是对这段代码的引用,这和变量的定义是相似的。没有事先定义函数而直接调用,就相当于在引用一个不存在的’变量名’。
形式一:无参函数
定义函数发生的事情
1)、申请内存空间保存函数体代码
2)、将上述内存地址绑定函数名
3)、定义函数不会执行函数体代码,但是会检测函数体语法
调用函数发生的事情
1)、通过函数名找到函数的内存地址
2)、然后加括号就是触发函数代码的执行
def foo():
print(foo) # foo是函数的内存地址,<function foo at 0x000002B9614C7430>
print('in the foo')
bar() def bar():
print('in the bar') # 调用阶段
foo()

# <function foo at 0x00000191556B9280>
# in the foo
# in the bar

形式二:有参函数
def fun1(x, y):
print(x, y) fun1(1, 2) def fun2(a):
print(a) fun2('hello world') # 1 2
# hello world
形式三:空函数,函数体代码为pass
def fun3(x, y):
pass # pass充当函数体“占位符”
# 三种形式的应用场景
# 函数类似于工厂,参数类似于原料,return产品,场景看你是否需要,pass,主要用于构思框架的时候用

三、 调用函数

1、语句的形式:只加括号调用函数
fun()
2、表达式形式:
def func1(x, y):
res = x + y
return res res1 = func1(1, 2)
print(res1)
# 3、函数调用可以当做参数
res2 = func1(func1(1, 2), 10)
print(res2)

四、 函数返回值

return是函数结束的标志,既函数体代码一旦运行到return会立刻终止函数的运行,并且会将return后的值当作本次运行的结果返回
1、返回None:函数体内没有return
return
return None
2、返回一个值:return 值
3、返回多个值:用逗号分隔开多个值,会被return返回成元组
def func():
return 1, 'an', [1, 23] res = func()
print(func(), type(func())) # (1, 'an', [1, 23]) <class 'tuple'>

五、 函数参数使用

一、形参与实参介绍
形参:在定义函数阶段定义的参数称之为形式参数,简称形参,相当于变量名
def func(x,y):
print(x,y)
实参:在调用函数阶段传入的值称之为实际参数,简称实参,相当于变量值
func(1,2)
实参和形参之间的关系:
在调用有参函数时,实参(值)会赋值给形参(变量名)。
在Python中,变量名与值只是单纯的绑定关系,而对于函数来说,这种绑定关系只在函数调用时生效,在调用结束后解除。

形参即在定义函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值。

实参即在调用函数时,括号内传入的值,值可以是常量、变量、表达式或三者的组合:
#1:实参是常量
res=my_min(1,2)

#2:实参是变量
a=1
b=2
res=my_min(a,b)

#3:实参是表达式
res=my_min(10*2,10*my_min(3,4))

#4:实参可以是常量、变量、表达式的任意组合
a=2
my_min(1,a,10*my_min(3,4))
二、形参与实参的具体使用
2.1 位置参数:在定义函数时,按照从左到右的顺序依次定义形参,称为位置形参,凡是按照这种形式定义的形参都必须被传值
特点:按照顺序与形参一一对应,实参个数比形参个数多一个不行,少一个也不行。
def register(name, age, sex):  # 定义位置形参:name,age,sex,三者都必须被传值
print('Name:{} Age:{} Sex:{}'.format(name, age, sex)) register('lq', 18, 'male') # TypeError:缺少3个位置参数
2.2 关键字参数:在调用函数时,实参可以是key=value的形式,称为关键字参数,凡是按照这种形式定义的实参,
可以完全不按照从左到右的顺序定义,但仍能为指定的形参赋值。指名道姓给某个形参传值,可以不参照顺序。
register(sex='male',name='lili',age=18)
需要注意在调用函数时:
实参也可以是按位置或按关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值
register('lili', sex='male', age=18)  # 正确使用
register(name='lili', 18, sex='male') # SyntaxError:关键字参数name=‘lili’在位置参数18之前
register('lili', sex='male', age=18, name='jack') # TypeError:形参name被重复赋值
2.3 默认参数:在定义函数时,就已经为形参赋值,这类形参称之为默认参数,当函数有多个参数时,
需要将值经常改变的参数定义成位置参数,而将值改变较少的参数定义成默认参数。
特点:在定义阶段就已经被赋值,意味着在调用阶段可以不用为其赋值
def register(name, age, sex='male'):  # 默认sex的值为male
print('Name:%s Age:%s Sex:%s' % (name, age, sex)) register('tom', 17) # 大多数情况,无需为sex传值,默认为male
register('Lili', 18, 'female') # 少数情况,可以为sex传值female
需要注意:
默认参数必须在位置参数之后
默认参数的值仅在函数定义阶段被赋值一次,准确的说被赋予的是值的内存地址
范例1
m=1
def func(x,y=m):
print(x,y) m=223222
func(2)
范例2
m = ['a', ]
def func(x, y=m): # y--->['a',]的内存地址
print(x, y)
m.append('b')
func(2) # 2 ['a', 'b']
虽然默认值可以被指定为任意数据类型,但是不推荐使用可变类型
函数最理想的状态:函数的调用只跟函数本身有关系,不受外界代码的影响

def fun(x, y, z, l=[]):
l.append(x)
l.append(y)
l.append(z)
print(l)
l = ['a', 'b']
fun(1, 2, 3)
print(l) # [1, 2, 3]
# ['a', 'b'] def fund(x,y,z,l=['a','b']):
l.append(x)
l.append(y)
l.append(z)
print(l)
fund(1,2,3)
fund(4,5,6) # ['a', 'b', 1, 2, 3]
# ['a', 'b', 1, 2, 3, 4, 5, 6]

# 推荐使用形式:
def fune(x,y,z,l=None):
if l is None:
l=[]
l.append(x)
l.append(y)
l.append(z)
print(l)
fune(1,2,3)
fune(4,5,6) # [1, 2, 3]
# [4, 5, 6]
2.4 可变长度的位置参数(*与**的用法):参数的长度可变指的是在调用函数时,实参的个数可以不固定,而在调用函数时,
实参的定义无非是按位置或者按关键字两种形式,这就要求形参提供两种解决方案来分别处理两种形式的可变长度的参数
(实参用来为形参赋值的,所以对应着,针对溢出的实参必须有对应的形参来接受)
2.4.1 可变长度的位置参数:如果在最后一个形参名前加号,那么在调用函数时,溢出的位置实参,都会被接收,
以元组的形式保存下来赋值给该形参。*后跟的可以实任意的名,但约定俗成应该是args.
(1)
def func(x, y, *args):
print(x)
print(y)
print(args)
func(1, 2, 3, 4, 5, 6)
# 1
# 2
# (3, 4, 5, 6)
# 例:求多个值得和
def func(*args):
res = 0
for item in args:
res += item
return res
res = func(1, 2, 3, 4, 5, )
print(res) # 15

(2)*可以用在实参中,实参中带*,先*后的值打散成位置实参,打散就是一个循环遍历取值。

# 例:
def func(x,y,z):
print(x,y,z)
func(*[1,2,3]) # 1 2 3

(3)形参与实参中都带*

def func(x, y, *args):
print(x)
print(y)
print(args)
func(1, 2, *[3, 4, 5]) # [3,4,5]打散成三个元素,三个元素以元组存
# 1
# 2
# (3, 4, 5)
func(1, 2, [3, 4, 5]) # [3,4,5]一个元素,按元组存
# 1
# 2
# ([3, 4, 5],)
func(*'hello world') # 打散成单个元素,以元组存
# h
# e
# ('l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd')
2.4.2 可变长度的关键字参数
如果在最后一个形参名前加**,那么在调用函数时,溢出的关键字参数,都会被接收,以字典的形式保存下来赋值给该形参
**后跟的可以实任意的名,但约定俗成应该是kargs。
(1)
def func(x, y, **kwargs):
print(x)
print(y)
print(kwargs)
func(1, 2, a=3, c=4, d=5)
# 1
# 2
# {'a': 3, 'c': 4, 'd': 5}

(2)  **可以用在实参中(**后跟的只能是字典),实参中带**,先**后的值打散成关键字实参

def func(x, y, z):
print(x, y, z)
func(**{'x': 3, 'y': 4, 'z': 5})
func(*{'x': 3, 'y': 4, 'z': 5}) # 循环遍历取了key
# 3 4 5
# x y z

(3) 形参与实参中都带*

def func(x, y, **kwargs):
print(x, y, kwargs)
func(1, 2, **{'a': 3, 'b': 4, 'c': 5})
# 1 2 {'a': 3, 'b': 4, 'c': 5}
2.5 命名关键字参数
命名关键字参数:在定义函数时,*后定义的参数,如下所示sex,age,称之为命名关键字参数
想要限定函数的调用者必须以key=value的形式传值,Python3提供了专门的语法:
需要在定义形参时,用作为一个分隔符号,*号之后的形参称为命名关键字参数。
对于这类参数,在函数调用时,必须按照key=value的形式为其传值,且必须被传值
def register(x, y, *, sex, age):
print(x, y, sex, age)
register(1, 2, sex='male', age=18) # 正确使用
# 1 2 male 18
register(1, 2, 'male', '18') # TypeError:未使用关键字的形式为sex和age传值
2.6 组合使用(*args必须在**kwargs之前)
综上所述所有参数可任意组合使用,但定义顺序必须是:位置参数、默认参数、*args、命名关键字参数、**kwargs。
可变参数*args与关键字参数**kwargs通常是组合在一起使用的,如果一个函数的形参为*args与**kwargs,
那么代表该函数可以接收任何形式、任意长度的参数。 
def func(*args, **kwargs):
pass
# 例:
def func(x, y, z):
print(x, y, z)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
wrapper(1, z=3, y=2)
# 1 2 3
'''
按照上述写法,在为函数wrapper传参时,其实遵循的是函数func的参数规则,调用函数wrapper的过程分析如下:
位置实参1被接收,以元组的形式保存下来,赋值给args,即args=(1,),关键字实参z=3,y=2被**kwargs接收,
以字典的形式保存下来,赋值给kwargs,即kwargs={'y': 2, 'z': 3}执行func(args,kwargs),即func((1,),**{'y': 2, 'z': 3}),
等同于func(1,z=3,y=2)提示: *args、**kwargs中的args和kwargs被替换成其他名字并无语法错误,但使用args、kwargs是约定俗成的。
'''

六、总结

0、引用传递
python中所有值得传递,传递的都是不是值本身,而是值得引用,既内存地址
1、函数分为两大类,分别是什么?二者在使用时有何区别
内置函数
自定义函数
2、什么是形参、什么是实参?形参与实参之间的关系是什么?
定义阶段和调用阶段
3、简述两只形参的区别:位置形参、默认形参
默认形参就在在定义阶段已给出值
ps:函数最理想的状态是函数的运行不受外界代码的干扰
def func(x,y,z=None):
if z is None:
z=[]
print(z)
4、简述两只实参的区别:位置实参、关键字实参
调用阶段func(1,2,a=3,b=3)
5、简述*和**在形参与实参中的区别(解决调用时,实参的个数与形参的个数不一样的问题)
def func(*args,**kwargs):
pass
func(1,2,3,4,a=5,b=6) 实参带*和**,就是打散,for循环的一个取值;形参中的*和**就汇总成元组和字典。 6、解释下述形式,既函数wrapper的参数特点是什么
def index(x,y,z):
print(x,y,z) def wrapper(*args,**kwargs) #形参汇总,args=(1,2),kwargs={'a':3,'b':4},
index(*args,**kwargs) #调用,实参打散,index(*(1,2),**{'a':3,'b':4})----->index(1,2,a=3,b=4) wrapper(1,2,a=3,b=4)


python基础六(函数基础及参数使用)的更多相关文章

  1. python学习7—函数定义、参数、递归、作用域、匿名函数以及函数式编程

    python学习7—函数定义.参数.递归.作用域.匿名函数以及函数式编程 1. 函数定义 def test(x) # discription y = 2 * x return y 返回一个值,则返回原 ...

  2. Python学习笔记-函数基础

    函数基础 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 为什么使用函数:减少重复代码.使程序变的可扩展使程序变得易维护 1.定义一个函数 #定 ...

  3. python学习总结 --函数基础

    函数基础 ### 函数简介 - 定义:具有特定功能的一段代码 - 优点: - 可以减少代码的重复书写 - 可以将功能的实现着和使用者分开,可以提高开发效率 - 分类: - 库函数:print.inpu ...

  4. Python学习day9 函数Ⅰ(基础)

    函数Ⅰ(基础) 三目运算 基本结构 v =  前面  if 条件 else 后面    #条件为真v=前面,条件为假v=后面.​#等同于if 条件: v = '前面'else:    v = '后面' ...

  5. Day9 Python基础之函数基础(七)

    参考链接:https://www.cnblogs.com/yuanchenqi/articles/5828233.html 1.函数的定义 定义: 函数是指将一组语句的集合通过一个函数名封装起来,要想 ...

  6. python学习日记(函数基础)

    修改文件(原理)--回顾 #修改文件(原理) with open('name','r',encoding='utf-8') as f,\ open('password','w+',encoding=' ...

  7. Python 入门基础12 --函数基础5 匿名函数、内置函数

    今日内容: 1.三元表达式 2.列表.元组生成式 | 字典生成式 3.递归 4.匿名函数 5.内置函数 一.三元表达式 三元运算符:就是 if...else... 语法糖 前提:if 和 else # ...

  8. python学习之函数基础

    第一个python函数: >>> def func_1(): ... print 'hello python' ... >>> func_1() hello pyt ...

  9. python学习之【第八篇】:Python中的函数基础

    1.前言 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 2.函数的定义 定义函数时需要遵守以下规则: 函数代码块以 def 关键词开头 ...

  10. Python 入门基础8 --函数基础1 定义、分类与嵌套使用

    目录 零.了解函数 一.函数的组成 二.函数的定义 三.函数的使用 四.函数的分类 五.函数的嵌套使用 零.了解函数 1.什么是函数 在程序中函数就是具备某一功能的工具 2.为何用函数 为了解决以下问 ...

随机推荐

  1. NC15033 小G有一个大树

    题目链接 题目 题目描述 小G想要把自己家院子里的橘子树搬到家门口(QAQ..就当小G是大力水手吧) 可是小G是个平衡性灰常灰常差的人,他想找到一个这个橘子树的平衡点. 怎么描述这棵树呢...就把它看 ...

  2. NAND flash 扫盲博客

    从SSD角度学习NAND Flash(一)_小小单片机的博客-CSDN博客 从SSD角度学习NAND Flash(二)_ssd和nand 的交互_小小单片机的博客-CSDN博客 从SSD角度学习NAN ...

  3. 【Unity3D】缩放、平移、旋转场景

    1 前言 ​ 场景缩放.平移.旋转有两种实现方案,一种是对场景中所有物体进行同步变换,另一种方案是对相机的位置和姿态进行变换. ​ 对于方案一,如果所有物体都在同一个根对象下(其子对象或孙子对象),那 ...

  4. Java I/O 教程(九) FileWriter和FileReader

    FileWriter Java FileWriter 用于往文件中写入字符数据. 不像FileOutputStream类,你无需转换字符串成字节数组,因为它提供了直接写字符串的方法. 类定义 publ ...

  5. form表单如何实现ajax提交

    最近在开发一个游戏网关的后台管理系统,总结了下中间碰到的一些问题. 之一就是:form表单如何实现ajax提交? 问题:在使用form表单的时候,一旦点击提交触发submit事件,一般会使得页面跳转, ...

  6. Divisors of the Divisors of an Integer题解

    Divisors of the Divisors of an Integer 题意:定义d[x]为x的因子个数,sndd[y]为y的因子的因子个数和. 思路:任意一个大于一的数,都可以分解为若干个质数 ...

  7. windows 程序启动后挂到后台

    开发中遇到一个问题,程序启动后,并没有出现在前台,而是自动挂到后台,程序处于卡死状态,基本任何模块都没加载进来. 后面排查发现跟一个功能的第三方 dll 有关系,在那个 dll 加载时导致程序卡死,因 ...

  8. 【Android逆向】IDA动态调试JNI_OnLoad 和 .init_array

    由于 JNI_OnLoad 和 .init_array 执行时间很早,so一加载到内存中就执行了,所以动态调试步骤会稍微要麻烦一些 1. 进入手机, 执行./android_server (如果是64 ...

  9. 使用paramiko模块远程连接遇到paramiko.ssh_exception.NoValidConnectionsError的解决办法

    连接时报错paramiko.ssh_exception.NoValidConnectionsError, 解决办法 首先在ubuntu终端上输入:cat /etc/ssh/ssh_config,查看端 ...

  10. 【LeetCode递归】括号生成,使用dfs

    括号匹配 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合. 示例 1: 输入:n = 3 输出:["((()))","(() ...