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后面 字典
posted @ 2017-06-25 23:31  gzz041  阅读(344)  评论(0)    收藏  举报