Python菜鸟起飞day5--函数

目录

一、函数的特性

二、函数的参数

1、必需参数

2、关键字参数

3、默认参数

4、不定长参数

5、参数混合定义

三、函数返回值

四、变量的作用域

1、全局变量与局部变量

2、作用域类型

2.1、L(local)局部作用域

2.2、E(enclosing)嵌套作用域

2.3、G(global)全局作用域

2.4、B(built-in)内置作用域

3、global和nonlocal关键字

3.1、global关键字

3.2、nonlocal关键字

3.3、locals()函数

3.4、example

四、递归函数(实例)

1、阶乘

2、斐波那契数列

五、重要的内置函数

1、filter()

2、map()

3、reduce()

4、lambda : 匿名函数

5、综合实例



一、函数

在python的世界里,函数和我们之前的[1,2,3],'abc',8等一样都是对象,而且函数是最高级的对象(对象是类的实例化,可以调用相应的方法,函数是包含变量对象的对象)

1.1、函数的定义

无论在模块中还是在类中都是使用def关键字来定义一个函数,然而在类中还有很多特殊的函数,并且类中的每个函数的第一个参数都是self(除了静态函数(staticmethod)和类函数(classmethod)等)。

另外,函数内部还可以再定义函数,成为函数的嵌套,被写在内部的函数叫做嵌套函数。详见,闭包和装饰器。

1.2、函数在内存中的存储情况

Python菜鸟起飞day5--函数_第1张图片

如图所示变量a,b中存储的地址指向了值8,所以系统打印a或者b的值的时候,就会根据这个地址找到8,然后打印。类似的,当你在变量foo的后面加上()来运行这个函数的时候,系统也会根据变量foo内存储的地址,将函数体内的代码加载到内存中去,然后再执行。因此,也可以将foo赋值给变量bar,只需要执行语句bar = foo即可。


二、函数的参数

1、必需参数

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

#必需参数
def info1(age):
    print(age)
info1(23)

2、关键字参数

如果你有一些具有许多参数的函数,而你又希望只对其中的一些进行指定,那么你可以通过命名它们来给这些参数赋值。

#关键字参数
def info2(name,age):
    print(name,age)
info2(age=23, name='zhuzihan')

3、默认参数

函数在声明是给形参赋默认值。传参时,该形参没有接收到传入实参,则使用默认值。

#默认参数
def info3(age,name='zhuzihan'):
    print(name,age)
info3(23,'zzh')

4、不定长参数

不定长的参数传入时可传入元组和字典。一遍在定义函数的时候,使用*args接收元组,**kwargs接收字典。

def add(*args):
    print(type(args))#
    s = 0
    for v in args:
        s += v
    return s
print(add(1,2,3,4))
def info4(**kwargs):
    for i,v in kwargs.items():
        print(i,v)

5、参数混合定义

def info4(*args,name='alex',**kwargs): 


假如如上所示定义函数,则:

 info4(name='zzh',*(23,175),**{'gender':'male','weight':65})


这样传参是不会出现错误

info4(name='alex',23,175,gender='male',weight=65)


这样传参则会提示错误

info4('alex',23,175,gender='male',weight=65)


则会将第一个传入的参数传给name形参。

因此,为避免不必要的错误,所以一般将必需参数或者默认参数等放在最前面,*args需要在**kwargs的前面。并且使用关键字参数的形式传入参数
 


三、函数返回值

1、函数在执行过程中,只要遇到return语句,就会停止执行,所以也可以将return理解为函数的结束。

2、在python中每个函数都有返回值,没有明确给出返回值的,默认返回None

3、当在函数中返回多个对象,则解释器会将这多个对象装成一个元组返回。

4、在python中,可以将函数名作为返回值。详见:装饰器

def t():
    return 1,2,3,'123'
print(t(),type(t()))

输出结果:

(1, 2, 3, '123') 

四、变量的作用域

以下内容摘抄https://www.cnblogs.com/fireporsche/p/7813961.html和自己的一些理解

1、全局变量与局部变量

         全局变量在全局范围内起作用,局部变量仅在函数内部起作用。在Python中并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。

          变量名解析:在一个模块(在一个py文件中)在类和函数中可以定义局部变量,并且python在寻找变量的时候,首先寻找的是“最局部的变量”。在一般情况下,函数中的变量相对于模块来讲,是局部变量,模块中的变量相对于整个项目来讲是局部变量,python中的内置变量,所有的模块都能访问,应该是“最全局”的变量了。

        注意:我在学习python的过程中,有一个不算弯的弯,一下子没反应过来。在下面代码中的lis在整个模块中也是一个在模块任何地方都能访问的变量。

def add():
    s = 0
    for value in lis:
        s += value
    return s

if __name__ == '__main__':
    lis = [1,2,3,4]
    print(add())

 

2、作用域类型

      在Python中,使用一个变量时并不严格要求需要预先声明它,但是在真正使用它之前,它必须被绑定到某个内存对象(被定义、赋值);这种变量名的绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量。

2.1、L(local)局部作用域

        局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。

        局部变量域就像一个栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。

2.2、E(enclosing)嵌套作用域

        E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。与L的区别在于,对一个函数而言,L是定义在此函数内部的局部作用域,而E是定义在此函数的上一层父级函数的局部作用域。主要是为了实现Python的闭包,而增加的实现。

2.3、G(global)全局作用域

        即在模块层次中定义的变量,每一个模块都是一个全局作用域。也就是说,在模块文件顶层声明的变量具有全局作用域,从外部开来,模块的全局变量就是一个模块对象的属性。
        注意:全局作用域的作用范围仅限于单个模块文件内。

2.4、B(built-in)内置作用域

系统内固定模块里定义的变量,如预定义在builtin 模块内的变量。

以上内容摘抄https://www.cnblogs.com/fireporsche/p/7813961.html和自己的一些理解

3、global和nonlocal关键字

3.1、global关键字

      1. 在一个模块中,函数要操作模块中的全局变量,不可直接修改。需要使用global关键字,在函数中声明

x = 100
def func():
    global x
    print(x)
    x = 2
    print(x)
func()
print(x)

      2.在函数里面声明一个全局变量

def fun(x):
    global a
    a = x +2
    return a
fun(3)
print(a)

3.2、nonlocal关键字

nonlocl用于闭包中,nonlocal就是在闭包中怎样对上一层函数内的变量进行更改。

x = 123
def outer():
    x = 100
    def inter():
        nonlocal x
        x = x + 1
    print(x)
    return inter()
outer()
print(x)

输出结果:

101
123

3.3、locals()函数

locals():会以字典类型返回当前位置的全部局部变量

def runoob(arg):    # 两个局部变量:arg、z
    z = 1
    print (locals())    
runoob(4)

输出结果:

{'z': 1, 'arg': 4}

3.4、example

x = int(2.9)

v_out = 10
def outer():
    global v_out
    global v_outer
    v_outer2 = 20
    v_outer = 10
    print("v_outer in outer %d"%v_outer)
    def inner():
        global v_inner
        nonlocal v_outer2
        v_outer=5
        v_inner = 5
        v_outer2 = 5
        print("v_outer in inner %d"%v_outer)
        print("v_out in inner %d"%v_out)
        print("v_inner in inner %d"%v_inner)
        print("v_outer2 in inner %d"%v_outer2)
    inner()
    print("v_inner in outer %d"%v_inner)
outer()
print("v_outer in global %d"%v_outer)
print("v_inner in global %d"%v_inner)

输出结果:

v_outer in outer 10
v_outer in inner 5
v_out in inner 10
v_inner in inner 5
v_outer2 in inner 5
v_inner in outer 5
v_outer in global 10
v_inner in global 5

四、递归函数(实例)

自己调用自己。

1、阶乘

def factorial(n):
    n = int(n)
    if n > 1:
        return factorial(n-1)*n
    else:
        return 1
     
print(factorial(5))

2、斐波那契数列

取出斐波那契数列中第n个数字。

def fibo(n):
    if n > 2:
        num = fibo(n-1)+fibo(n-2)
        return num
    elif n==2:#下面两条语句是规定前两个数字是0和1
        return 1
    else:
        return 0;
 
print(fibo(6))

五、重要的内置函数

1、filter()

根据传入的函数,将str中的每一个元素依次使用function判定,为True则返回,否则丢弃

s1 = ['a', 'b','c', 'd']
   
def fun1(s):
    if s != 'a':
        return s
#根据传入的函数,将str中的每一个元素依次使用function判定,为True则返回,否则丢弃
ret = filter(fun1, s1)
print(type(ret),list(ret))# ret是一个迭代器对象 

输出结果:

 ['b', 'c', 'd']

2、map()

对sequence中的item依次执行function(item),将执行结果组成一个map object迭代器返回.map也支持多个sequence,这就要求function也支持相应数量的参数输入。

s1 = [1, 2,'a', 'b']
   
def fun2(s):
    s = str(s)
    return s + "alvin"
   
ret = map(fun2, s1)
   
print(type(ret),ret)      #  map object的迭代器
print(list(ret))

输出结果:

['aalvin', 'balvin', 'calvin', 'dalvin']

3、reduce()

from functools import reduce
   
def add1(x,y):
    return x + y
print (reduce(add1, range(1, 10)))##(注:1+2+...+9)
print (reduce(add1, range(1, 10), 20))## (注:1+2+...+9+20)

输出结果:

45
65

4、lambda : 匿名函数

lambda 传入的参数:函数体

#普通函数
def add(a,b):
    return a + b
print(add(2,3))
  
#匿名函数
add = lambda a,b : a + b
print(add(2,3))

输出结果:

5
5

5、综合实例

from functools import reduce
print(reduce(lambda x,y:x*y,range(1,5)))#依次从列表中取出1,2,3,4做积。即1*2=2 2*3=6 6*4=24

seq = map(lambda x:x*x,range(1,5))#将[1,2,3,4]中的元素依次取出来,平方后,放到列表中
print(list(seq))

输出结果:

24
[1, 4, 9, 16]

第一遍学习python。跟以前学习的语言有很多不同。特别是细节方面,python的很多方面都令我折(wu)服(nai)。以上整理的笔记,有缘人若发现错误或者表述不贴切的地方,万望指出。小弟于此先行谢过。



 

 

 

 

 

你可能感兴趣的:(Python学习,cpython,函数,参数,lambda)