Python-06-函数

2019-07-24 09:16:00来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

一、函数的定义

函数是第一类对象,即函数可以当作数据传递

#1 可以被引用
#2 可以当作参数传递
#3 返回值可以是函数
#3 可以当作容器类型的元素

 

1. 定义方式

def 函数名(参数1,参数2,参数3,...):
    '''注释'''
    函数体
    return 返回的值

2. 函数的返回值

  无return->None

  return1个值->返回1个值

  return 逗号分隔多个值->元组

二、函数的调用

1. 调用的方法

函数的调用:函数名加括号

  • 先找到名字
  • 根据名字调用代码

2. 先定义,再调用

函数即“变量”,“变量”必须先定义后引用。未定义而直接引用函数,就相当于在引用一个不存在的变量名
#测试一
def foo():
    print('from foo')
    bar()
foo() #报错

#测试二
def bar():
    print('from bar')
def foo():
    print('from foo')
    bar()
foo() #正常

#测试三
def foo():
    print('from foo')
    bar()
    
def bar():
    print('from bar')
foo() #会报错吗?


#结论:函数的使用,必须遵循原则:先定义,后调用
#我们在使用函数时,一定要明确地区分定义阶段和调用阶段

#定义阶段
def foo():
    print('from foo')
    bar()
def bar():
    print('from bar')
#调用阶段
foo()

 三、函数的参数

1. 位置参数

按照从左到右的顺序定义的参数

  位置形参:必选参数

  位置实参:按照位置给形参传值

2、关键字参数

按照key=value的形式定义的实参无需按照位置为形参传值 ,

注意的问题:

  1. 关键字实参必须在位置实参右面

  2. 对同一个形参不能重复传值

3、默认参数

形参在定义时就已经为其赋值可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参

注意的问题:

  1. 只在定义时赋值一次

  2. 默认参数的定义应该在位置形参右面

  3. 默认参数通常应该定义成不可变类型

4. 可变长参数

可变长指的是实参值的个数不固定, 而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs

def test(x, *args, **kwargs):
    print(x)
    print(args)
    print(kwargs)    
test(1, *[2, 3, 4, 5], **{'y': 2, 'z': 3})

运行结果:
1
(2, 3, 4, 5)
{'y': 2, 'z': 3}
def test(x, *args, **kwargs):
    print(x)
    print(args)
    print(kwargs)
test(1, 2, 3, 4, 5, y=2, z=3)

运行结果:
1
(2, 3, 4, 5)
{'y': 2, 'z': 3}

 四、全局变量和局部变量

顶头写的是全局变量

函数内部的是局部变量

global指定全局变量

nonlocal指定上一级的变量

name = "刚娘" 
def weihou():
    name = "陈卓"
    def weiweihou():
        global name   # global,指定全局变量
        name = "冷静"

    weiweihou()
    print(name)

print(name)
weihou()
print(name)

# 刚娘
# 陈卓
# 冷静
name = "刚娘"
def weihou():
    name = "陈卓"
    def weiweihou():
        nonlocal name   # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
        name = "冷静"

    weiweihou()
    print(name)

print(name)
weihou()
print(name)

# 刚娘
# 冷静
# 刚娘

 五、风湿理论(函数即变量)

# def foo():
#     print('from foo')
#     bar()
#
# foo()
# 报错

# def bar():
#     print('from bar')
# def foo():
#     print('from foo')
#     bar()
#
# foo()
# 不报错


# def foo():
#     print('from foo')
#     bar()
#
# def bar():
#     print('from bar')
# foo()
# 不报错

# def foo():
#     print('from foo')
#     bar()
#
# foo()
# 
# def bar():
#     print('from bar')
# 报错

 六、递归

1. 定义

如果一个函数在内部调用自身本身,这个函数就是递归函数

def calc(n):
    print(n)
    if n // 2 == 0:
        return
    return calc(n / 2)
calc(10)

10
5.0
2.5
1.25

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

七、函数的作用域

1. 作用域即范围

  - 全局范围(内置名称空间与全局名称空间属于该范围):全局存活,全局有效
    - 局部范围(局部名称空间属于该范围):临时存活,局部有效

2. 作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关

x=1
def f1():
    def f2():
        print(x)
    return f2
x=100
def f3(func):
    x=2
    func()
x=10000
f3(f1())

3. 查看作用域:globals(),locals()

LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间

八、匿名函数

匿名函数lambda x: x * x实际上就是:

def f(x):
    return x * x

关键字lambda表示匿名函数,冒号前面的x表示函数参数。

匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25

同样,也可以把匿名函数作为返回值返回,比如:

def build(x, y):
    return lambda: x * x + y * y

 


原文链接:https://www.cnblogs.com/lsf123456/p/11150750.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:【第六篇】Python数据类型--list&amp;tuple&amp;dict&amp;set

下一篇:python 基础学习笔记(3)--列表与元组