Python基础10-函数基础

目录

函数的定义

函数的返回值

函数的参数

参数的传递

参数的默认值

可变长参数

全局变量与局部变量

函数嵌套定义

风湿理论——函数即变量


函数的定义

定义函数的关键字def。函数名,本例函数名是test。小括号里面是参数。冒号后缩进的代码块是函数内容。函数的注释用""",使用双引号是为了规范。return返回值。pass说明函数结束,其实pass不加也没问题,但是为了规范还是写上吧。

Python解释器逐行解释,如果函数test定义一次以后,再定义一个函数test,那么就test就以最后一次定义的为准。

def test(x):
    """
    function test
    :param x: 整数
    :return: 返回x的立方值
    """
    y = x ** 3
    return y
    pass


def test():
    """
    function test
    这就重新定义了函数test
    :return: 9527
    """
    return 9527
    pass


val = test()
print(val)
# 9527

函数的返回值

Python的返回值和Java一样也是只有一个返回值。因为Python有了元组这个容器类型,所以多个返回值可以被转换为一个元组返回。看起来可以返回多个值,而且实际上你也可以这么用。

def func01():
    """
    如果没有返回值,那么返回的是None
    :return: None
    """
    msg = "func01"
    print(msg)


def func02():
    """
    返回一个值
    :return: msg
    """
    msg = "func02"
    print(msg)
    return msg


def func03():
    """
    如果返回多个值,那么返回的是这多个值组成的元组。
    实际上是返回一个值,元组。但是你可以用多个变量来接收这个元组的元素。
    :return: 
    """
    msg = "func03"
    print(msg)
    return msg, [11, 22, 33], 28, "Kevin"


t1 = func01()
t2 = func02()
t3 = func03()
val, li, num, name = func03()
print(t1)
print(t2)
print(t3)
print(val, li, num, name)
# None
# func02
# ('func03', [11, 22, 33], 28, 'Kevin')
# func03 [11, 22, 33] 28 Kevin

函数的参数

参数的传递

函数的参数分为实参和形参。

func04的参数xyz都是形参。形参只在函数被调用时分配内存空间,函数调用结束以后内存空间就被释放。

函数传参可以传位置参数,就是按照形参顺序传参,不能多也不能少。

函数传参可以传关键字参数,就是形参名=实参,顺序无所谓,不能多也不能少。

位置参数和关键字参数可以混搭使用。位置参数必须在关键字参数前面,传参总个数不能多也不能少。

def func04(x, y, z):
    print(x, y, z, sep=",")
    return


# 位置参数,按照顺序传参,不能多也不能少
func04(11, 22, 33)
# 关键字参数,按照关键字传参,顺序无所谓,不能多也不能少
func04(z=33, x=11, y=22)
# 位置参数和关键字参数可以混用
# 位置参数 必须在 关键字参数 前面,不能多也不能少
func04(11, 22, z=33)

参数的默认值

函数的参数可以有默认值。非默认值参数必须放在默认值参数前面。调用时,非默认参数必须传值,默认值参数可以不传值。参数不用默认值时,用关键字参数指定哪个参数不用默认值。

def func05(app, db="mysql", os="linux"):
    """
    非默认值参数放在默认值参数前面。
    默认数据库是mysql,默认操作系统是linux。
    :param app: 应用
    :param db: 数据库
    :param os: 操作系统
    :return: None
    """
    print("%(app)s, %(db)s, %(os)s." % ({"app": app, "db": db, "os": os}))
    pass


# 默认值参数不用传输 
# discuzz, mysql, linux.
func05("discuzz")

# 参数不用默认值时,最好用关键字参数,指定哪个参数不是默认的值
# httpd, mysql, freebsd.
func05("httpd", os="freebsd")

可变长参数

传入多个参数,*对应列表,**对应字典。

函数参数加上*args,函数就可以接收多个位置参数,按照Python规则*args就这么写。*args接收位置参数,除去前面的位置参数,多出来的被处理成元组args。如果传入的是列表,那么列表就是元组args的一个元素。如果传入的*列表,那么就把列表的元素处理成元组args的元素。

def func06(x, y, *args):
    """
    *args接收位置参数,将多个参数处理成元组。
    此时,函数可以接收多个参数,出去前面的位置参数,后面的多个参数处理成元组
    如果传入的是个列表,那么这个列表就是元组args的一个元素。
    如果传入的列表元素都变成args的元素,那么传参时需要加*。*对应列表
    :param x:
    :param y:
    :param args:
    :return:
    """
    print(x)
    print(y)
    print(args)
    pass

# 1
# 2
# ()
func06(1, 2)

# 1
# 2
# (3, 4, 5, 6)
func06(1, 2, 3, 4, 5, 6)

# 1
# 2
# ([3, 4, 5, 6],)
func06(1, 2, [3, 4, 5, 6])

1
2
(3, 4, 5, 6)
func06(1, 2, *[3, 4, 5, 6])

函数加上**kwargs,函数就可以接收多个关键字参数,按照Python规则就这么写。接收的多个关键字参数被处理成字典kwargs。如果要传入字典的话,字典前面加上**。

def func07(x, y, **kwargs):
    """
    *kwargs接收关键字参数,将多个关键字参数处理成字典。
    此时,函数可以接收多个关键字参数,除去前面的位置参数,后面的多个关键字参数被处理成字典
    如果传入的是字典,需要在字典前面加**
    :param x:
    :param y:
    :param kwargs:
    :return:
    """
    print(x, y)
    print(kwargs, kwargs.get("k1"))
    pass


# 1 2
# {'k1': 'v1', 'k2': 'v2'} v1
func07(1, 2, k1="v1", k2="v2")
# 1 2
# {'k1': 'v1', 'k2': 'v2'} v1
func07(1, 2, **{"k1": "v1", "k2": "v2"})

如果函数参数加上了*args和**kwargs,那么这个函数就可以接收任意的参数了。这样有利于未来的扩展。接收的参数怎么处理是函数实现的问题。

def func08(x, y, *args, **kwargs):
    """
    现在这个函数牛逼了
    :param x: 
    :param y: 
    :param args: 
    :param kwargs: 
    :return: 
    """
    print(x, y)
    print(args)
    print(kwargs, kwargs.get("k1"))
    pass


# 1 2
# (3, 4, 5, 6)
# {} None
func08(1, 2, 3, 4, 5, 6)

# 1 2
# ()
# {'a': 5, 'b': 9} None
func08(1, 2, a=5, b=9)

# 1 2
# (3, 4, 11, 22, 33, 44)
# {'k1': 'v1', 'k2': 'v2', 'k3': 9527} v1
func08(1, 2, 3, 4, *[11, 22], *[33, 44], **{"k1": "v1", "k2": "v2"}, k3=9527)

全局变量与局部变量

全局变量作用于全局。局部变量作用于代码块。执行函数时,先找局部变量,局部变量找不到再找全局变量。如果要直接访问全局变量,那么要用global声明。Python编程规范,全局变量全部大写,局部变量全部小写,这样以后就不会出现变量名重合的情况了。

name = "Kevin"
name1 = "Tom"


def change_name():
    global name
    name = "Alice"
    name1 = "Jerry"
    print(name, name1)
    pass


# Alice Jerry
# Alice Tom
change_name()
print(name, name1)

函数嵌套定义

函数里面还可以再定义函数。如果出现global,那么global变量就是全局变量。这段代码func12将全局变量name的值从Able改成了Charlie。

name = "Able"


def func11():
    name = "Baker"

    def func12():
        global name
        name = "Charlie"
        pass

    func12()
    print(name)
    pass


print(name)
func11()
print(name)

函数里global只的就是全局变量,而另一个关键字nonlocal指的是上一层的变量。这段代码,func12里面将func11的局部变量name的值从Baker改为Charlie。

name = "Able"


def func11():
    name = "Baker"

    def func12():
        nonlocal name
        name = "Charlie"
        pass

    func12()
    print(name)
    pass


print(name)
func11()
print(name)
# Able
# Charlie
# Able

风湿理论——函数即变量

Python的风湿理论?靠,什么鬼名字。这里的意思是函数都可以看成是函数名的字符串。只要在这个字符串里面的变量或者函数曾经出现在内存中,就可以找到,继续执行不会报错。

这个例子中func14虽然定义在func13之后,但是根据风湿理论,程序逐行执行,func13和func14都会先作为变量保存在内存中。调用func13时,执行func13代码块,遇到调用func14,因为func14已经存在了,找得到,所以不会报错。

def func13():
    print("from func13")
    func14()
    pass


def func14():
    print("from func14")
    pass


# from func13
# from func14
func13()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章