Python之函数

 

函数基础知识

 

1. 函数的作用(面向函数编程的优点):
    a. 解决代码冗余
    b. 提高代码可读性
    c. 提高了代码的重用性
    d. 增强了代码的可扩展性
    e. 解耦:把一个大功能尽量拆开来,尽量细化成多个小功能,并且功能与功能之间的影响减到最小

  面向对象编程:功能与功能之间耦合很紧密

 

2. 函数基本形式

def func(arguments):  # def 定义函数
    '''
    注释部分
    :param arguments:
    :return:
    '''
    '''函数体部分'''
    return arguments  # return 函数结束并返回arguments


func('test')  # 调用函数 并传入字符串test作为参数


3. 关键字 return

    1. 作用
       a. 返回值
       b. 结束函数的执行
    2. 返回值
       a. 单个值(任意类型的对象)
       b. 多个值(示例 return 1,2,3) 需用','分隔,接收时数据类型为元组,可以用一个变量或多个变量接收,多个变量接收需注意个数保持一致
      c. 当函数没有return时,默认返回值为None

 

4. 函数的参数

  1. 实参和形参

def mylength(name):  # name参数 站在函数定义的角度上,所有的函数都是形式参数(形参)
    print(name)
    n = 0
    for i in name:
        n += 1
    print(n)

mylength("alex")     # alex参数 站在函数调用的角度上,所有的参数都是是实际参数(实参)

 

  2. 位置参数、关键字参数、默认参数(任意数据类型)

def func(parameter1, parameter2, default_parameter=None):
    '''
    :param parameter1: 位置参数1 必须传的参数
    :param parameter2: 位置参数2
    :param default_parameter: 默认参数 可以不传值 默认None
    :return:
    '''
    print(parameter1, parameter2, default_parameter)

func(1,2)   # 按位置传参,即顺序传参
func(parameter2=1,parameter1=2) # 按关键字传参,即根据不同参数名传参,无所谓顺序
func(1, parameter2=2)  # 混用:必须先按位置传参,再按照关键字传参

 

   3. 当函数中的默认参数为可变数据类型时

def demo(a = []):
    a.append(123)
    print(a)

demo()  # 此次没有传值 所有a=[] 执行完后a=[123]
demo([])    # 传入[] a=[] 执行完后a=[123]
demo()  # 没有传值 此时a=[123] 执行完后a=[123, 123]

   注意:因为参数a是可变数据类型(列表、字典),在第三次调用函数时,内存中保存的a并不是空列表,而是第二次执行完毕的结果, 所以,第三次执行完是有两个元素的

 

4. 动态参数

  * 是动态参数的表识

  a. *args  代表位置参数

  b. **kwargs 代表关键字参数

def func1(*args):  # 站在函数定义的角度上,*做聚合用,将参数合成元组
    print(*args)    # * 在这里起打散作用
    print(args)     # 聚合之后是元组

func1(1, 2, 3)


def func2(*args):
    print(*args)
    print(args)

li = (1, 2, 3)
print(*li)  # 打散作用
func1(*li)   # 站在函数调用的角度上,*做打散用,将一个列表或元组打散成多个参数


def func3(**kwargs):    # 站在函数定义的角度上,**做聚合用,将参数合成字典
    print(kwargs)

func3(a=1, b=2)

def func4(**kwargs):
    print(kwargs)

d = {'c': 3, 'a': 1, 'b': 2}
func4(**d)  # 站在函数调用的角度上,**做打散用,将一个字典打散成多个参数

 

5. 命名空间和作用域

  命名空间又叫做名称空间,分为三种
    启动python
    a. 先加载Python内置命名空间 这里边存放了python解释器为我们提供的名字:input,print,str,list,tuple等
    b. 加载全局命名空间的名字,从上到下加载,除去函数内部,其余都是全局空间
    c. 加载局部空间中的名字,调用该函数的时候,从上到下加载
      局部命名空间之间的数据不能共享,局部命名空间可以调用全局变量, 对于局部命名空间来说,自己有就用自己的,自己没有就用全局的

  作用域,即不同命名空间下的变量的作用域

    内置的命名空间,在任意地方都可以用
    全局的命名空间,在我们写的代码里任何地方
    局部命名空间,在自己写的函数内使用
  
  范围从大到小:内置 全局 局部--->局部
  作用域: 站在范围小的局部,如果有 用局部,局部没有往上找,就近原则往上找,找到第一个可用的名字就用它

  PS:对于不可变的数据类型,如果想在函数内部修改想对全局生效,就要进行global生明;对于可变数据类型,如果想修改直接修改即可


6. 关键字 global nonlocal

  globals()全局,不受影响
  global 变量 #在局部里面改变全局变量,只改变全局变量,不影响其他的变量

  locals()局部,放局部里就只显示局部的
  nonlocal 变量 #只改变局部里的变量,从内部往外部找到的第一个变量名

a = 0
def demo1():
    a =1
    def demo2():
        global a  # global,只是改变全局变量,不会影响其他局部的变量
        a=2
        print(a)
    demo2()
    print(a)
demo1()
print(a)

 

a = 0
def demo1():
    a = 1
    def demo2():
        nonlocal a  # 只改变上一层的a---->a=2
        a = 2
        print(a)
    demo2()
    print(a)

demo1()
print(a)

 

7. 函数的本质
  函数名(是一个存着函数地址的变量名)是第一类对象的概念
  函数名首先是一个函数的内存地址,可以赋值,可以作为其他列表等容器的元素,可以作为函数的参数返回

 

8. 小练习(斐波那契数列)

# 当长度小于多少时
l = [1,1]
while len(l)<20:
    l.append(l[-2]+l[-1])
print(l)

#当小于某一个数时
l = [1,1]
while l[-1]<40000:
    l.append(l[-2]+l[-1])
print(l)

 

posted @ 2018-10-28 17:23  chitalu  阅读(130)  评论(0编辑  收藏  举报