python函数详解

函数


函数返回值

return代表一个函数的结束,不会再操作return后面的代码

没有返回值,默认是返回None

  • 不写return
  • 只写return:结束一个函数
  • 写 return None

返回一个值

return和返回值之间要有空格,可以返回任意数据类型的值

如果有多个return,只执行到第一个return就结束

返回多个值

可以返回任意多个、任意数据类型的值

返回的多个值会被组织成元组被返回

也可以用多个变量来接收(有多少返回值就用多少变量接收)

函数参数

定义函数参数的顺序:先定义位置参数,*args,定义默认参数,最后**kwargs

#函数定义
def mylen(s1):
    """计算s1的长度"""
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen("hello world")
print('str_len : %s'%str_len)

我们告诉mylen函数要计算的字符串是谁,这个过程就叫做 传递参数,简称传参,我们调用函数时传递的这个“hello world”和定义函数时的s1就是参数

形参与实参

形参:定义函数时的s1,只是一个变量的名字,被称为形式参数,因为在定义函数的时候它只是一个形式,表示这里有一个参数。

**实参:调用函数时传递的这个“hello world”被称为实际参数,**因为这个是实际的要交给函数的内容。

位置参数

站在实参角度

1.按照位置传值

def mymax(x,y):
    #此时x=10,y=20
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)

2.按照关键字传值

def mymax(x,y):
    #此时x = 20,y = 10
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(y = 10,x = 20)
print(ma)

​ 3.位置、关键字形式混着用

  • 必须要先按照位置传参,再按照关键字传参
  • 不能给同一个变量传多个值
def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(10,y = 20)
print(ma)

站在形参角度

  • 位置参数必须传值,且有几个必须传几个
def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

#调用mymax不传递参数
ma = mymax()
print(ma)

#结果
TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'

默认参数

1.正常使用

使用方法

为什么要有默认参数:将变化比较小的值设置成默认参数

2.默认参数的定义

def stu_info(name,sex = "male"):
    """打印学生信息函数,由于班中大部分学生都是男生,
        所以设置默认参数sex的默认值为'male'
    """
    print(name,sex)


stu_info('alex')
stu_info('eva','female')

如果默认参数的值是一个可变数据类型,那么每一次调用函数的时候,如果不传值就公用这个数据类型

def defult_param(a,l = []):
    l.append(a)
    print(l)

defult_param('alex')
defult_param('egon')

>>>['alex']
>>>['alex', 'egon']

动态参数

按位置传值多余的参数都由args统一接收,保存成一个元组的形式

def mysum(*args):   # *args可以接收多个参数 按照位置传参 返回元组
    the_sum = 0
    for i in args:
        the_sum+=i
    return the_sum

the_sum = mysum(1,2,3,4)
print(the_sum)

**kwargs使用关键字传参,返回字典类型数据

def stu_info(**kwargs):
    print(kwargs)
    print(kwargs['name'],kwargs['sex'])

stu_info(name = 'alex',sex = 'male')

函数的注释

# 函数的注释
def func(参数1,参数2):
    '''
    这个函数实现了什么功能
    :param 参数1: 
    :param 参数2: 
    :return: 函数的返回值
    '''
    pass
总结

定义函数的规则:

1.定义:def 关键词开头,空格之后接函数名称和圆括号()2.参数:圆括号用来接收参数。若传入多个参数,参数之间用逗号分割。
    参数可以定义多个,也可以不定义。
    参数有很多种,如果涉及到多种参数的定义,应始终遵循位置参数、*args、默认参数、**kwargs顺序定义。
    如上述定义过程中某参数类型缺省,其他参数依旧遵循上述排序
3.注释:函数的第一行语句应该添加注释。
4.函数体:函数内容以冒号起始,并且缩进。
5.返回值:return [表达式] 结束函数。不带表达式的return相当于返回 None

def 函数名(参数1,参数2,*args,默认参数,**kwargs):
        """注释:函数功能和参数说明"""
        函数体
        ……
        return 返回值

调用函数的规则:

1.函数名()
    函数名后面+圆括号就是函数的调用。
2.参数:
    圆括号用来接收参数。
    若传入多个参数:
        应按先位置传值,再按关键字传值
        具体的传入顺序应按照函数定义的参数情况而定
3.返回值
    如果函数有返回值,还应该定义“变量”接收返回值
    如果返回值有多个,也可以用多个变量来接收,变量数应和返回值数目一致

无返回值的情况:
函数名()

有返回值的情况:
变量 = 函数名()

多个变量接收多返回值:
变量1,变量2... = 函数名()

在这里插入图片描述

函数进阶

命名空间和作用域

命名空间

  • 内置命名空间(input,print,str,list,tuple…)——python解释器
    • 就是python解释器一启动就可以使用的名字存储在内置命名空间中
    • 内置的名字在启动解释器的时候被加载进内存里
  • 全局命名空间 —— 我们写的代码但不是函数中的代码
    • 是在程序从上到下被执行的过程中依次加载进内存的
    • 放置了我们设置的所有变量名和函数名
  • 局部命名空间 ——函数
    • 就是函数内部定义的名字
    • 当调用函数的时候 才会产生这个名称空间 随着函数执行的结束 这个命名空间就消失了

在局部:可以使用全局、内置命名空间中的名字

在全局:可以使用内置命名空间中的名字,但是不能用局部中的

在内置:不能使用局部和全局的名字

三种命名空间之间的加载与取值顺序:

**加载顺序:**内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

取值:

  • 在局部调用:局部命名空间->全局命名空间->内置命名空间
  • 在全局调用:全局命名空间->内置命名空间
  • 当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字

作用域

全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围生效

在全局调用globals和locals

print(globals())
print(locals())

在局部调用globals和locals

def func():
    a = 12
    b = 20
    print(locals())
    print(globals())

func()

对于不可变数据类型 在局部是可以查看全局作用域中的变量 但是不能直接修改

如果想要修改,需要在程序的一开始添加global声明

global关键字

如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的操作有效

a = 10
def func():
    global a
    a = 20

print(a)
func()
print(a)

函数的嵌套和作用域链

函数的嵌套调用

def max2(x,y):
    m  = x if x>y else y
    return m

def max4(a,b,c,d):
    res1 = max2(a,b)
    res2 = max2(res1,c)
    res3 = max2(res2,d)
    return res3

max4(23,-7,31,11)

函数的嵌套定义

def f1():
    print("in f1")
    def f2():
        print("in f2")

    f2()
f1()

# -------------------------------------------------
def f1():
    def f2():
        def f3():
            print("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
    
f1()

函数的作用域链

def f1():
    a = 1
    def f2():
        print(a)
    f2()

f1()

# ---------------------------------------------
def f1():
    a = 1
    def f2():
        def f3():
            print(a)
        f3()
    f2()

f1()

# ----------------------------------------------
def f1():
    a = 1
    def f2():
        a = 2
    f2()
    print('a in f1 : ',a)

f1()

nonlocal关键字

  • nonlocal 只能用于局部变量 找上层中离当前函数最近一层的局部变量
  • 声明了nonlocal的内部函数的变量修改会影响到 离当前函数最近一层的局部变量
def f1():
    a = 1
    def f2():
        nonlocal a
        a = 2
    f2()
    print('a in f1 : ',a)

f1()

函数名的本质(函数名本质上就是函数的内存地址)

  • 可以被引用
def func():
    print('in func')

f = func
print(f)   # <function func at 0x00000175DD92C378>

print(f())   # in func   None
  • 可以被当作容器类型的元素
def f1():
    print('f1')


def f2():
    print('f2')


def f3():
    print('f3')

l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#调用
l[0]()
d['f2']()
  • 可以当作函数的参数和返回值
def func():
    print(123)
    
def wahaha(f):
    f()
    
wahaha(func)

# --------------------------------------------------
def func():
    print(123)
    
def wahaha(f):
    f()
    return f
    
qqxing = wahaha(func)
qqxing()

闭包

闭包函数:

内部函数包含对外部作用域而非全局作用域名字的引用,该内部函数称为闭包函数
#函数内部定义的函数称为内部函数

def func():
    name = 'eva'
    def inner():
        print(name)
    return inner

f = func()
f()

判断闭包函数的方法__closure__

#输出的__closure__有cell元素 :是闭包函数
def func():
    name = 'eva'
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f = func()
f()

#输出的__closure__为None :不是闭包函数
name = 'egon'
def func2():
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f2 = func2()
f2()

闭包的嵌套

def wrapper():
    money = 1000
    def func():
        name = 'eva'
        def inner():
            print(name,money)
        return inner
    return func

f = wrapper()
i = f()
i()

闭包函数获取网络应用

from urllib.request import urlopen

def index():
    url = "http://www.xiaohua100.cn/index.html"
    def get():
        return urlopen(url).read()
    return get

xiaohua = index()
content = xiaohua()
print(content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值