函数

一.函数简介

  1. 函数是可重用的程序代码块
  2. 函数也是对象
  3. 对代码实现了封装,并增加了函数调用*,传递参数,返回结果等内容*

二.Python函数分类

  1. 内置函数

str(),list(),len()等

  1. 标准库函数

通过import语句导入库

  1. 第三方库函数

下载安装后,通过import语句导入库

  1. 自定义函数

三.函数定义

  1. 定义语法:
    def 函数名([参数列表]):
    ‘’'文档字符串‘’‘
    函数体/若干语句
  2. 要点:
    a. 执行def()语句时,会创建一个函数对象,并绑定到函数名变量上
    b. 如果函数体不包含return语句,返回None值
    c. 调用函数前,必须先定义函数,即调用def()创建函数
  3. 形参和实参
  4. 文字档字符串
    a. 文档的注释,用三个单引号或双引号实现,中间可以有多行文字说明

注意:三个单引号也可以定义多行字符串
b. help(函数名.doc)可以输出函数文档字符串

  1. 返回值
    a. return:结束函数执行并返回值
    b. 不包含return:返回None值
    c. 要返回多个值,使用元组,列表,字典,集合存起来即可
  2. 圆括号意味调用函数,没有圆括号时,python会把函数当作普通对象(可以赋值)
  3. 变量的作用域:
    a. 全局变量:
    - 定义位置直到模块结束
    - 降低了通用性和可读性,尽量避免使用
    - 函数要改全局变量,用global声明,否则视为局部变量
    b. 局部变量:
    - 引用比全局变量快,优先考虑使用
    - 如果和全局变量重名,函数内只用局部变量
    c. print(locals()):输出局部变量
    print(globals()):输出全局变量

四.参数的传递

  1. 参数的传递都是引用传递,不是值传递,分为两类:
    a. 对可变对象(字典,列表,集合,自定义)进行写操作,直接作用于原对象本身
    b. 对不可变对象(数字,字符串,元组,函数)进行写操作,产生一个新的对象空间,用新值填充(当传递的不可变对象的子对象是可变对象时,函数修改这个可变对象,原对象也发生变化)
a=(10,20,[5,6])
print("a:",id(a))
def test06(m):
    print("m:",id(m))
    m[2][0]=888
    print(m)
    print("m:",id(m))   #m的地址一直没有发生改变,因为m始终指向a指向的元组
    
test06(a)
print(a)     #a也发生了改变

五.浅拷贝与深拷贝

a. 浅拷贝:不拷贝子对象的内容,只拷贝子对象的引用
b. 深拷贝:将子对象的内存全部拷贝,对子对象的修改不会影响原对象

#浅拷贝和深拷贝
import copy           #要导入copy
def testcopy():
    ''' 测试浅拷贝'''
    a=[10,20,[5,6]]
    b=copy.copy(a)

    print("a:",a)
    print("b:",b)
    b.append(30)
    b[2].append(7)
    print("浅拷贝")
    print("a:",a)
    print("b:",b)

def testdeepcopy():
    '''测试深拷贝'''
    a=[10,20,[5,6]]
    b=copy.deepcopy(a)
    print("a:",a)
    print("b:",b)
    b.append(30)
    b[2].append(7)
    print("深拷贝")
    print("a:",a)
    print("b:",b)
testcopy()
testdeepcopy()

六.参数的几种类型

  1. 位置参数
  2. 默认值参数

调用时未赋值,按照定义时的值运算,若调用时赋值,则改用新值

  1. 命名参数

无所谓顺序,但注意不可重复赋值

  1. 可变参数(可放多个参数)
    a.一个星号表示元组
    b. 两个星号表示字典
  2. 强制命名参数

在可变参数后的参数,调用时必须命名

def test07(a,b,c,d):
    print("a")
def test08(a,b,c=10,d=45):
    print("b")

test07(1,2,3,4)
test08(2,3,4)
#test07(7,8,a=4,b=1)   #报错,必须都赋值或者按顺序来
test07(7,8,c=4,d=1) 

#可变参数
def test09(a,b,*c):
   print(a,b,c)
def test10(*a,b,c):
    print(a,b,c)
def test11(a,b,*c,**d):
    print(a,b,c,d)
    
test09(1,2,3,4,5,6)
test10(1,2,3,b=4,c=5)
test11(1,2,3,4,5,name="gaogao",job="teacher",sex="female")  #注意字典中的键不要用引号!!!

七.lambda表达式

  1. lambda函数是一种简单的,在同一行中定义函数的方法
  2. 生成一个函数对象
  3. 只允许包含一个表达式
  4. 基本语法:lambda arg1,arg2,arg3…:<表达式>
f=lambda a,b,c:a+b+c     
print(f)
print(f(2,3,4))

g=[lambda a:a*2,lambda b:b+2,lambda c:c**2] #g是一个列表,里面每个元素是一个lambda函数生成的函数对象
print(g[0](6),g[1](3),g[2](8))

#测试evla函数
a=1
b=2
c=eval("a+b")

dict1=dict([("a",1),("b",2)])   #注意引号
dict2=dict(zip(["a","b"],[1,2]))
print(dict1)
c=eval("a+b",dict1)   #按照字典中的对应键值赋值并计算(是逗号!!)
print(c)

八.eval()函数

  1. 字符串str当成有效的表达式求值并返回计算结果
  2. 可以结合字典进行对应赋值运计算
a=1
b=2
c=eval("a+b")

dict1=dict([("a",1),("b",2)])   #注意引号
dict2=dict(zip(["a","b"],[1,2]))
print(dict1)
c=eval("a+b",dict1)   #按照字典中的对应键值赋值并计算(是逗号!!)
print(c)

九.递归函数

  1. 必备条件:
    a. 终止条件
    b. 递归步骤(第n步与第n-1步关联)
  2. 递归会创建大量函数对象(每次调用函数,都会创造一个栈帧),消耗内存与运算能力
  3. 递归是分层思想,但是在列计算式时,要考虑的是完整的关系式
#递归函数
#算阶乘
def factoria(n):
    if n==1:
        return 1
    return n*factoria(n-1)

for x in range(1,5):
    print(x,"!=",factoria(x))  #要用逗号隔开!!

十. 嵌套函数

  1. 子函数的定义和调用都在函数内部完成
  2. 作用:
    a. 封装(数据隐藏):外部无法访问嵌套函数
    b. DRY原则:避免代码重复(将操作细节放入代码内部,增加参数)
    c. 闭包
#普通
def printChineseName(name,familyName):
    print("{0} {1}".format(familyName,name))
def printEnglishName(name,familyName):
    print("{0} {1}".format(name,familyName))
#使用嵌套函数,将细节隐藏在函数内部
def printName(isChinese,name,familyName):   #多加了一个参数
    def inner_print(a,b):
        print("{0} {1}".format(a,b))
    if isChinese:
        inner_print(familyName,name)
    else:
        inner_print(name,familyName)

printName(True,"xiaoqi","Gao")
    

十一.nonlocal关键字

  1. nonlocal声明外部的局部变量;global声明全局变量
  2. 若不用nonlocal或global,可以读但不能写
  3. 若用nonlocal声明,在嵌套函数内,该变量不能出现在nonlocal前面
a=100

def outer():
    b=10
    def inner():
        #print(b)   #SyntaxError: name 'b' is used prior to nonlocal declaration(当有nonlocal时不可以在nonlocal前使用)
        global a
        nonlocal b
        a=80
        b=100
        print("a,b is:",a,b)

    inner()
outer()

LEGB规则

  1. local->enclosed->global->built-in
#测试LEGB搜索规则
#str="haha"
def outer():
    #str="enclosed"
    def inner():
        #str="local"
        print(str)
    inner()
outer()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值