zoukankan      html  css  js  c++  java
  • 函数入门

    函数

    引入

    什么是函数?

    函数就是一种工具,可以重复使用

    为什么要用函数?

    防止代码冗余和增强代码的可读性

    怎么用函数?

    先定义后使用

    函数的定义规范

    def 函数名(参数1,参数2...):
    	'''文档描述'''
        函数体
        return 值
    #主要由关键字def+函数名(尽量为有意义的)+():组成
    

    def:定义函数的关键字

    函数名:函数名指向函数内存地址,是对函数体代码的引用。函数名一般为有意义的,可以反映出函数的功能

    函数名:命名规范与变量名命名规范一致
    1、一定不要与关键字冲突
    2、一定要见名知意

    括号:括号内定义参数,参数是可有可无的,且无需指定参数的类型

    冒号:括号后要加冒号,然后在下一行开始缩进编写函数体代码

    文档描述:描述函数功能,参数介绍等信息的文档,非必要,但建议加上,从而增强函数的可读性

    函数体:由语句和表达式组成了

    return:定义函数的返回值,可有可无

    函数的类型

    无参函数

    def login(): #括号里面无参数
        print('登陆成功')
    

    有参函数

    username = input('请输入你的用户名:')
    def login(username):
    	print(username)
    

    空函数

    def login():  #一般常用在编写多功能程序时构建项目框架,用pass充当函数体占位符
        pass
    

    调用函数与函数返回值

    函数的使用分为定义阶段与调用阶段,定义函数时只检测语法,不执行函数体代码

    不写return

    #不写return默认返回None
    def login():
        print('success')
    
    
    print(login())
    #结果为
    success
    None
    

    只写return:只有结束函数体代码的作用,默认返回None

    写return None:与只写return效果一样

    return返回一个值:可以将返回的结果,当作一个变量使用

    return返回多个值:1 将返回的多个值存入一个元组

    ​ 2 返回值不想被修改

    ​ 3 可以指定返回的数据类型

    形参与实参介绍

    形参即在定义函数时,括号内声明的参数。形参本质就是一个变量名,用来接收外部传来的值。

    实参即在调用函数时,括号内传入的值,值可以是常量、变量、表达式或三者的组合,实参本质就是一个变量值

    PS:在调用有参函数时,实参(值)会赋值给形参(变量名)。在Python中,变量名与值只是单纯的绑定关系,而对于函数来说,这种绑定关系只在函数调用时生效,在调用结束后解除。

    函数的传参方式

    位置参数:按照参数位置去传参
    def register(name, age, sex):  # 定义位置形参:name,age,sex,三者都必须被传值    		print('Name:%s Age:%s Sex:%s' % (name, age, sex))
        
        
    register('sean', 66, 'boy')  #按照从左往右的先后顺序将值传给对应的参数
    #输出结果为
    Name:sean Age:66 Sex:boy
    
    关键字参数:指定参数进行传值,与参数位置无关
    def register(name, age, sex):
        print(f'Name:{name}, Age:{age}, Sex:{sex}')
    
    
    register(age=73, name='tank', sex='male')
    #输出结果为
    Name:tank, Age:73, Sex:male
    

    PS:需要注意在调用函数时,实参也可以时按位置或关键字的混合使用,但必须保证关键字参数在位置参数后面,且不可以对一个形参重复赋值

    def register(name, age, sex):
        print('Name:{1},Age:{0}, Sex:{2}'.format(age, name, sex))
    
    
    register(age=73, name='sean', sex='male')
    register(sex='male', 18, name='sean')
    register('tank', sex='male', age=18, name='sean')
    #输出结果为
    Name:sean,Age:73, Sex:male
    SyntaxError: positional argument follows keyword argument
    TypeError: register() got multiple values for argument 'name' 
    

    默认参数

    def register(name, age, sex='male'):
        print('名字:{}, 年龄:{}, 性别:{}'.format(name,age,sex))
    
    
    register('sean', 27) 
    register('tank', 73, sex='female')
    #输出结果为
    名字:sean, 年龄:27, 性别:male  #这里我们在定义函数时,就设置了默认参数sex='male'
    名字:tank, 年龄:73, 性别:female #因为我们自己设定了传参的值
    
    #PS:
    #	 默认参数必须在位置参数之后
    #    默认参数的值仅在函数定义阶段被赋值一次
    #    如果在实参的时候传入了一个新的参数,就会使用新参数
    #    默认参数在传值时,不要将可变类型当作参数传递
        
    #每次调用都是在上一次的基础上向同一列表增加值
    def foo(n,arg=None):
        if arg is None:
            arg = []
            arg.append(n)
            print(arg)
    foo(1)
    foo(2)
    foo(3)
    #输出结果为
    [1]
    [2]
    [3]
    
    

    可变长参数

    可变长位置参数

    #如果在最后一个形参名前加*号,那么在调用函数时,溢出的位置实参,都会被接收,以元组的形式保存下来赋值给该形参
    #   *args:接受所有溢出的位置参数;接受的值都被存入一个元组
    def foo(a, b, c, *args):
        print(a, b, c, *args)  #这里写为*args的话相当于直接将其当成一个正常的参数来用;也可以理解为*将默认得到的元组拆分了
    	print(a, b, c, args)   
    
    foo(1, 2, 3, [4, 5, 6])
    #输出结果为
    1 2 3 [4, 5, 6]
    1 2 3 ([4, 5, 6],)   #默认将溢出的值存入一个元组
    
    
    def foo(a, b, c, *args):
        print(a, b, c, args)
        print(a, b, c, *args)
    
    
    foo(1, 2, 3, 4, 5, 6)
    #输出结果为
    1 2 3 (4, 5, 6)
    1 2 3 4 5 6
    #PS:两个对比我们可以得到,*号的作用打散你传入的容器类型
    
    
    #求和小练习
    def sum(*args):
        a = 0
        for i in args:
            a += i
        print(a)
        
    
    sum(10, 11, 12)  
    
    

    可变长关键字参数

    #如果在最后一个形参名前加**,那么在调用函数时,溢出的关键字参数,都会被接收,以字典的形式保存下来赋值给该形参
    def foo(a, **kwargs):  #在最后一个参数kwargs前加**
        print(a, kwargs)
    	print(a, *kwargs)
    
    foo(b=1, a=2, c=3)    #溢出的关键字实参b=1,c=3都被**接收,以字典的形式保存下来,赋值给kwargs
    #输出的结果为
    2 {'b': 1, 'c': 3}
    2 b c                #字典打散则取key
    
    
    def foo(x, y, **kwargs):
        print(x, y, kwargs)
        
        
    dic = {'a':1, 'b':2}
    foo(1, 2, **dic)
    #输出结果为
    1 2 {'a': 1, 'b': 2}
    #PS:
    #实参可以直接定义字典传值给形参
    #形参为常规参数时,实参可以是**的形式
    
    

    命名关键字参数

    在定义了**kwargs参数后,函数调用者就可以传入任意的关键字参数key=value,如果函数体代码的执行需要依赖某个key,必须在函数内进行判断

    def register(name,age,**kwargs):
        if 'sex' in kwargs:  #有sex参数
            print('...')
        if 'height' in kwargs:
            print('***')     #有height参数
    
    
    register('sean', 18, sex = 'male')
    #输出结果为
    ...
    
    

    想要限定函数的调用者必须以key=value的形式传值,Python3提供了专门的语法:需要在定义形参时,用*作为一个分隔符号,星号之后的形参称为命名关键字参数。对于这类参数,在函数调用时,必须按照key=value的形式为其传值,且必须被传值

    def register(name,age,*,sex,height): #sex,height为命名关键字参数
        pass
    
    
    register('lili',18,sex='male',height='1.8m') #正确使用
    
    #命名关键字参数可以有默认值
    def register(name,age,*,sex='male',height):
        print('Name:{},Age:{},Sex:{},Height:{}' .format(name, age, sex, height))
    
    
    register('tank', 18, height='1.8m') #这里我们没有传入sex的参数
    #输出的结果为
    #需要强调的是:sex不是默认参数,height也不是位置参数,因为二者均在*后,所以都是命名关键字参数,形参sex=’male’属于命名关键字参数的默认值,因而即便是放到形参height之前也不会有问题。另外,如果形参中已经有一个args了,命名关键字参数就不再需要一个单独的*作为分隔符号了
    
    def index(name, age, *args, sex = 'male', height):
        print(f'Name:{name}, Age:{age}, Args:{args}, Sex:{sex}, Height:{height}')
    
    
    index('sean', 18, 1, 2, 3, height='170')
    #输出结果为
    Name:sean, Age:18, Args:(1, 2, 3), Sex:male, Height:180
    
    
    综上所述所有参数可任意组合使用,但定义顺序必须是:位置参数、默认参数、*args、命名关键字参数、**kwargs
    可变参数args与关键字参数**kwargs通常是组合在一起使用的,如果一个函数的形参为args与**kwargs,那么代表该函数可以接收任何形式、任意长度的参数
    def func(x,y,z):
        print(x,y,z)
    def index(*args,**kwargs):
        func(*args, **kwargs)
    
    
    index(x=1,y=2,z=3)  #这里传的值可以是全为关键字参数或全为位置参数,或者混合使用
    #该函数执行的大概流程为定义函数func和index,然后调用函数index,而函数index中的代码块为执行func函数,()中的参数*args和**kwargs即为上面要输出的x,y,z
    
    

    按照上述写法,在为函数wrapper传参时,其实遵循的是函数func的参数规则,调用函数wrapper的过程分析如下:

    1. 位置实参1被*接收,以元组的形式保存下来,赋值给args,即args=(1,),关键字实参z=3,y=2被**接收,以字典的形式保存下来,赋值给kwargs,即kwargs={'y': 2, 'z': 3}
    2. 执行func(args,kwargs),即func(*(1,),** {'y': 2, 'z': 3}),等同于func(1,z=3,y=2)

    提示: *args、**kwargs中的args和kwargs被替换成其他名字并无语法错误,但使用args

  • 相关阅读:
    xBIM 基本的模型操作
    xBIM 应用与学习 (二)
    xBIM 应用与学习 (一)
    ABP WebApi 加载错误
    ABP 数据迁移
    AutoDesk Forge 获取令牌认证
    IIS 加载 JSON 错误 404 解决办法
    ASP.NET MVC 5 ABP DataTables (二)
    ASP.NET MVC 5 ABP DataTables (一)
    Windows10卡顿,磁盘 内存占用100%或比较多
  • 原文地址:https://www.cnblogs.com/a736659557/p/11892349.html
Copyright © 2011-2022 走看看