函数及其参数应用

函数

函数就是具有某个具体功能的工具,函数可以帮助我们提高开发效率,避免代码过于繁琐,提高程序等的扩展性。

如何定义?

关键词:def

规则:函数名的命名规则与变量名一致,不能以关键字命名(*****),命名要做到见名知意。

# 函数在定义的时候只检测函数体的语法,不执行函数的代码。

***调用函数的固定格式:函数名() 

# 函数名只要遇到括号就会立刻执行函数体代码;

# 代码中遇到函数名加括号,优先级最高;

# 先去执行函数,再看下面的代码。

函数包括有内置函数、自定义函数:

内置函数:python提前给你写好了的函数,直接调用就可以。如len()

自定义函数:必须先定义后调用****定义了的函数可以在任意位置调用。如:

l = [1,2,3,4,5]
def my_len():  # 自定义函数
    n = 0
    for i in l:
        n += 1
    print(n)  # 5
res = my_len()
print(res)  # None
# 由此可以看出,目前定义的函数有两个问题:
1.没有返回值,只能固定的执行打印操作
2.只能够固定的统计某一个容器类型的长度。

要想函数内返回给调用者值,必须用关键词return

①不写return:函数默认返回None。如:

def func():
    print('hahaha')  # hahaha
res = func()
print(res)  # None

②只写return:返回的也是None。如:

def func():
    l = ['jason','egon','tank']
    while True:
        for i in l:
            if i == 'egon':
                # break
                return  # 当i为egon的时候 直接结束函数运行
            print(i)  # jason
res = func()
print(res)  # None

ps:return除了可以返回值之外,还可以直接结束整个函数的运行。

③写return None:跟只写return是一样的。

④写return返回一个值:这个值可以是python任意类型数据。如:

def func():
    return '123'
def func1():
    return [1,2,3]
def func2():
    return {'name':'jason'}
def func3():
    return (1,)
def func4():
    return {1,2,3,4,5}
def func5():
    return True
print(func())  # 123
print(func1())  # [1, 2, 3]
print(func2())  # {'name': 'jason'}
print(func3())  # (1,)
print(func4())  # {1, 2, 3, 4, 5}
print(func5())  # True

可以看到,return返回的值可以是整型、列表、字典、元祖、集合、布尔值等各种python类型数据。

写return返回多个值:return会自动将多个值一元祖的形式返回给调用者。如:

def func():
    return 1,2,3,4  
res = func()
print(res)  # 返回的是(1, 2, 3, 4)


def func1():
    return [1,2,3],[1,2,3],[1,2,3] 
res1 = func1()
print(res1)   # 返回的是([1, 2, 3], [1, 2, 3], [1, 2, 3])


def func2():
    return {'name':'jason'},{'username':'tank'},{'user_name':'egon'} 
res2 = func2()
print(res2)   # 返回的是({'name': 'jason'}, {'username': 'tank'}, {'user_name': 'egon'})


# 不管你return的什么值,结果都以元祖的形式给你返回

如何不返回元祖?>>>自己手动加上你想返回的数据类型。如:

def func3():
    return [[1,2,3,4],[1,2,3,4],[1,2,34]]  # 想要返回的是列表类型
res3 = func3()
print(res3)  # 返回的是[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 34]]  列表类型

 小结:

1.所有的函数都有返回值,无论写不写return,不写的情况下默认为None。

2.只写return或return None并不是为了考虑返回值,而是为了结束函数的运行。

 函数的参数:形参和实参

形参:函数的定义阶段,()内写的变量名是该函数的形式参数

实参:函数的调用阶段,()内实际传入的值叫做实际参数

关系:形参相当于变量名,实参相当于变量的值。(函数调用传参的过程,就是给形参变量名赋值的过程)

注意:形参与实参的绑定关系只在函数的调用阶段有效,函数运行结束后关系自动解除。此外,只在函数内部有效,函数外部无任何影响

因此现在可以总结出函数的简易结构

def 函数名(形参1,形参2......) :

  """函数的注释,用来描述该函数的作用以及各个参数的类型"""

  函数体代码1

  函数体代码2

  ...

  return  函数的返回值

如:

def func(x,y) :
    """
    该函数的作用
    :param x:对形参x的解释
    :param y:对形参y的解释
    :return:对函数返回值的解释
    """
    print('ncegfbr')
    return 'ubvjhrsb'

此外,print(help(func))可以查看内置函数及自定义函数的注释。

位置参数:

位置形参:在函数定义阶段按照位置从左到右依次书写变量名,叫做函数的位置形参。(位置形参在调用的时候,必须为其传值)如:

def my_max(x,y):
    print(x,y)
    if x > y :
        return x
    else :
        return y
res = my_max(1)  # 报错(在调用函数的时候,少一个参数不行)
res = my_max(1,2,3)  # 报错(在调用函数的时候,多一个参数不行)
res = my_max(1,2)  # 结果为2,表明此时是一一对应关系,x对应1,y对应2

位置实参:在函数调用阶段,传入的参数会按照位置一一对应给形参。

ps:两种传参方式:

①直接按照位置以一对一,也就是上面的例子。

②指名道姓的传(关键字传参)

如:

def my_max(x,y):
    print(x,y)
    if x > y :
        return x
    else :
        return y
res = my_max(x=1,y=2)  

除此之外,还可以位置和关键字混合使用,如:

def my_max(x,y):
    print(x,y)
    if x > y :
        return x
    else :
        return y
res = my_max(1,y=2)  

但是,混合使用必须保证位置参数在关键字参数前面,且同一个形参不能被多次赋值。(越短越靠前,越长越复杂的越靠后)

 默认值参数:应用场景:当形参接收到的值比较单一的情况下)

在函数定义阶段,形参就已经被赋值了。

# 在调用的时候可以不为默认值形参传值,默认使用已经绑定的值;

# 在调用的时候如果可以给默认值形参传值,使用传后的值;

# 在定义阶段,默认值形参必须放啊在位置形参的后面。

如:

def register(username,age,gender='male'):  # 已经被赋值的gender就是默认为male
    print(username,age,gender)
register('jason',18)  # jason 18 male
register('tank',28)  # tank 28 male
register('egon',84)  # egon 84 male
register('kevin',58)  # kevin 58 male
register('xiaohou',17,'female')  # xiaohou 17 female  
# 第三个参数不传则默认为male,传的话就为传的值,在此为female

   *****************************

函数在定义阶段 内部所使用的变量都已经初始化完毕了
不会因为调用的位置的变化 而影响到内部的值(暂时可忽略)


函数无论在什么地方被调用
都会跑到函数定义阶段去执行代码
形参中用到的值都是往函数定义阶段代码往上找
**************************************

可变长参数:在形参和实参中用*和**表示不同的含义。

1.形参中*能够接收多余的位置参数,组织成一个元祖赋值给*后面的形参名。如:

def func(x,y,*z):
    print(x,y,z)  
func(1,2,3,4,5,6,7,8,54,43,4,5,6,6,7,8,)  # 阴影部分为多余的未知参数
# 结果为1 2 (3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8)
# 其中z(*后面的形参名) = (3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8) 元祖形式

2.形参中**能够接收多余的关键字参数,组织成一个字典赋值给**后面的形参名。如:

def func(x,y,**z):
    print(x,y,z)  
func(x=1,y=2,z=1,a=1,b=2,c=3)  # 阴影部分为多余的关键字参数
# 结果为1 2 {'z': 1, 'a': 1, 'b': 2, 'c': 3}
其中z(**后面的形参名 = {'z': 1, 'a': 1, 'b': 2, 'c': 3}

组成的字典:字典的value就是关键字的名字指向的值

3.实参中*能够将列表、元祖、集合、字符串打散成位置实参的形式传递给函数。如:

def func(x,y,z):
    print(x,y,z)
# func(*[1,2,3,4,5,6])  # *会将列表打散成位置实参一一传入等价于func(1,2,3,4,5,6)
func(*(1,2,3))  # 1 2 3     等价于func(1,2,3)
# *的内部你可以看成是for循环

 4.在实参中**能够将字典打散成 key = value 的形式,按照关键字参数传送给函数。如:

def func(x,y,z):
    print(x,y,z)
func(12,3,4)  # 12 3 4 位置传参
func(x=1,y=2,z=3)  # 1 2 3  关键字传参
d = {'x':1,'y':2,'z':333}  
func(**d)  # 1 2 333      # 等价于func(x=1,y=2,z=333)  **会将字典拆封成 key = value的形式

 *********************************************************

attention:python中推荐使用形参*和**通用的写法:

def func(*args,**kwargs) :

  print(args,kwargs)

func(?)  # 里面可以是任意类型数据,但必须是先位置传参,后关键字传参

原文地址:https://www.cnblogs.com/pupy/p/11158157.html