python -- 函数 function
python-- 函数 function
编程分类:
- 面向对象编程: 类 class
- 面向过程编程: 过程 def
- 函数式编程: 函数 def
编程语言中的函数定义:
函数,函数式逻辑结构化和过程化的一种编程方法。
# 定义一个函数,有return值的是函数
def func_1():
print('in the func_1')
return 0
# 定义一个过程,没有return的是过程
def func_2():
print('in the func_2')
a = func_1()
b = func_2()
# 这里是将func_1和func_2赋值给a_1和b_1,但是,没有调用,只要加()就可以调用
a_1 = func_1
b_1 = func_2
# 0
print(a)
# None
print(b)
print('--------------------')
# in the func_1
a_1()
# in the func_2
b_1()
为什么要使用函数?
没有函数的编程只是在写逻辑(功能),想脱离函数,重用你的逻辑,唯一的方法就是拷贝。
使用函数的三大优点
- 代码重用
- 保持一致性
- 可扩展性
函数的return那些事
- 函数可以没有return,即,过程
- return值可以是任意类型,int,'str',list,dict
- return值也可以是一个数学公式
- return也可以返回单个
- 如果没有return值,系统默认会返回None
- return一个函数名,即返回这个函数的内存地址
为什么要有返回值?
我们想看到调用这个函数执行完毕后的结果。
注意点:
- 函数在执行过程中只要遇到遇到return语句,就会停止执行并返回结果,可以理解成return就是函数的结束
- 如果未在函数中指定return,那么这个函数的返回值为None
| 返回数值 | 返回内容 | 备注 |
|---|---|---|
| 0 | 返回:None | 系统默认返回 |
| 1 | 返回:object | 返回return值 |
| >1 | 返回:tuple | 返回return值 |
函数的参数 位置参数 positional argument 关键字参数 keyword argument
函数func_1()中的x和y,又称位置参数positional argument。
# x和就是形参
def func_1(x, y):
print(x)
print(y)
print("##########[x='我是前者', y='我是后者']##########")
func_1(x='我是前者', y='我是后者')
print("##########[y='我是前者', x='我是后者']##########")
func_1(y='我是前者', x='我是后者')
print("##########['我是前者', '我是后者']##########")
# '我是前者', '我是后者' 这就是“实参”
func_1('我是前者', '我是后者')
'''
以下是程序的效果:
##########[x='我是前者', y='我是后者']##########
我是前者
我是后者
##########[y='我是前者', x='我是后者']##########
我是后者
我是前者
##########['我是前者', '我是后者']##########
我是前者
我是后者
'''
形参 vs 实参 vs 默认参数
形参,形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时接受实参。如果没有有默认参数,形参和实参需要一一对应。
实参,实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参。
区别:
形参是虚拟的,不占用内存空间,形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传递单向,实参传给形参,不能形参传给实参。
def func_1(x, y):
print(x)
print(y)
x = 1
y = 2
func_1(x=x, y=y)
'''
以下是程序的运行结果。
1
2
'''
位置参数和关键字,标准调用:实参与形参位置一一对应;关键字调用:位置无需固定。
默认参数特点: 调用函数的时候,默认参数非必须传递
默认参数用途: 默认设定
def func_1(x, y=3):
print(x)
print(y)
x = 1
y = 2
func_1(x=x, y=y)
'''
以下是程序的运行结果。
1
2
'''
参数组 *args(args无所谓,主要是*开头就行)
参数组的作用,为了程序的扩展。*args把不固定的参数都变成了元组tuple。
在调用函数时,给函数输入的形参数目不固定时,可以使用。
*args接收N个位置参数,不能接收关键字参数。并且把接收位置参数转换成元组。
def func_1(x, *args):
print(x)
print(args)
x = 1
y = [2, 3, 4, 5]
func_1(1, [2, 3, 4, 5]) # 等同于func_1(x, y)
'''
以下是程序的运行结果。
1
([2, 3, 4, 5],)
'''
def func_1(x=100, *args):
print(x)
print(args)
def func_2(*args):
print(args)
func_1(1, 2, 3, 4, 5)
func_1(*(11, 22, 33, 44, 55))
print('--------------------')
func_2(1, 2, 3, 4, 5)
func_2(*(11, 22, 33, 44, 55))
'''
1
(2, 3, 4, 5)
11
(22, 33, 44, 55)
--------------------
(1, 2, 3, 4, 5)
(11, 22, 33, 44, 55)
'''
参数组 **kwargs(kwargs无所谓,主要是**开头就行)
**kwargs的作用,把N个关键字参数(而不是位置参数),转换成字典的方式。
注意kwargs的书写格式
def func_1(**kwargs):
# print(kwargs)
return kwargs
u1_name = input('User Name:')
u1_age = int(input('User Age:'))
u1_job = input('User Job:')
u1 = func_1(name=u1_name, age=u1_age, job=u1_job)
# 上面的代码也可以写成下面的格式
# u1 = func_1(**{'name': u1_name, 'age': u1_age, 'job': u1_job})
print(type(u1), u1)
'''
以下是程序执行的结果:
User Name:user01
User Age:10
User Job:clerk
<class 'dict'> {'name': 'user01', 'age': 10, 'job': 'clerk'}
'''
位置参数 vs 默认参数 vs 参数组
def func_1(name, age=18, *args, **kwargs):
print(name)
print(age)
print(args)
print(kwargs)
func_1('User', 20, 'WTF', sex='M', hobby='None')
'''
以下是程序的效果:
User
20
('WTF',)
{'sex': 'M', 'hobby': 'None'}
'''
作用域 vs 局部变量 vs 全局变量
- def里面的name是局部变量
- def外面的name是全局变量
- def就是局部变量name的作用域
- def外面的test_code是全局变量,def里也可以调用
- def里面用global声明def里面要把全部变量改掉,永远不要这样用
def change_user_name(name):
# 这里可以修改全局变量
global test_code_1
test_code_1 = '我就是TEST-Code'
print('\033[31;1mbefore_name is {0}\033[0m'.format(name))
name = name.upper()
print('\033[32;1mafter_name is {0}\033[0m'.format(name))
# 这里调用全局变量test_code给函数内使用
print(test_code)
print(test_code_1)
name = input("Use Name:")
test_code = 'Code'
test_code_1 = 'Code_1'
change_user_name(name)
print('\033[33;1mNow the name is {0}\033[0m'.format(name))
# 我就是TEST-Code
print(test_code_1)
'''
以下是程序的效果,颜色的变化无法体现。
Use Name:gao
before_name is gao
after_name is GAO
Code
我就是TEST-Code
Now the name is gao
我就是TEST-Code
'''
全局变量 vs 局部变量
- 在子程序中定义的变量成为局部变量,在程序的一开始定义的变量称为全局变量。
- 全局变量作用域是正规程序,局部变量作用域是定义该变量的子程序。
- 当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用,在其他地方全局变量起作用。
除了简单的字符串和整数外,高级的列表,字典,集合,类都可以通过函数,把外面的内容修改了。
def change_name(name):
print('before change is {0}'.format(name))
name[0] = '我是def内的user01'
print('after change is {0}'.format(name))
name = ['user01', 'user02']
change_name(name)
print(name)
'''
以下是程序执行的结果:
before change is ['user01', 'user02']
after change is ['我是def内的user01', 'user02']
['我是def内的user01', 'user02']
'''
高阶函数
高阶函数,变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数。这就是高阶函数。
def add(x, y, f):
return f(x) + f(y)
res = add(3, -6, abs)
# 9
print(res)
函数式编程介绍 todo
这里介绍的函数式编程和python里面的函数变成,并非一码事。
函数是python内建支持的一种封装。python里的函数,更多的是定义一段代码的执行过程。
函数式编程的函数,不是数学的函数,而是计算机底层的函数。
写在后面
- 函数的参数,先位置,关键字后。(关键人物在最后)
- 过程和函数的异同性,相同点,两者都是可以调用的实体,区别是过程是没有返回值的函数。
- 有return值的是函数
- 没有return的是过程
- def里语句遇到return就结束
- 不要在def里面定义全局变量
- 更不要在def里面修改全局变量
| 参数 | 调用方式 | 备注 | 类型 |
|---|---|---|---|
| 关键字参数 | 关键字=参数 | 需要用=等号 | 传入什么类型就是什么类型 |
| 位置参数 | 与函数体位置一一对应 | 一一对应 | 传入什么类型就是什么类型 |
| *args | 将N个位置参数 | 在位置参数,关键字参数后面,**kwargs前面 | 元组 |
| **kwargs | 将N个关键字参数 | 在位置参数,关键字参数,**kwargs后面 | 字典 |

浙公网安备 33010602011771号