• Python之初识函数


    1、什么是函数?

    函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

    2、为什么使用函数?

    函数能提高应用的模块性,和代码的重复利用率。

    你已经知道Python提供了许多内建函数,比如print()。

    但你也可以自己创建函数,这被叫做用户自定义函数。

    3、函数的特性

    1)代码重用

    2)保持一致性

    3)可扩展性

    4、函数的创建

    定义函数使用 def 关键字,一般格式如下:
    # def 函数名(参数列表):
    #    函数体
    
    
    def hello():
        '''我是描述信息:描述该函数是干什么用的'''
        print('hello')
    
    
    hello()  # 调用
    print(hello.__doc__)   # 通过 hello.__doc__ 查看描述
    
    '''
    hello
    描述信息,描述该函数是干什么用的
    '''

    优雅取代多分支 if

    def foo():
        print('foo')
    
    def bar():
        print('bar')
    
    dic={
        'foo':foo,
        'bar':bar,
    }
    while True:
        choice=input('>>: ').strip()
        if choice in dic:
            dic[choice]()

     

    5、函数名的命名规则

    a、函数名必须以下划线或字母开头,可以包含任意字母、数字或下划线的组合。不能使用任何的标点符号;

    b、函数名是区分大小写的。

    c、函数名不能是保留字。


    6、函数的调用

    # 语句形式: foo() 或 m=foo() 会执行函数 foo,并输出屏幕
    def foo():
        print('foo')
    
    foo()
    m = foo()
    '''
    foo
    foo
    '''
    
    # 表达式形式:res=10*my_sum(1,2),先执行函数,如果有 print 就输出屏幕,并把函数结果*10赋值给 res
    def my_sum(a, b):
        print('test')
        return a+b
    
    res = 10*my_sum(1, 2)
    print(res)
    '''
    test
    30
    test
    '''
    
    # 函数调用作为另外一个函数的参数:print(my_sum(1,2))
    print(my_sum(1, 2))   # 3


    7、函数的参数

    a、形参和实参

    形参:形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时接收实参(实参个数,类型应与实参一一对应)

    实参:实际参数,调用函数时传给函数的参数,可以是常量,变量,表达式,函数,传给形参

    区别:形参是虚拟的,不占用内存空间,形参变量只有在被调用时才分配内存单元,实参是一个变量,占用内存空间,数据传送单向,实参传给形参,不能形参传给实参

    理解:实参本质是形参变量名的值,形参本质是变量名

    注意:实参不要传递可变的数据类型,因为在函数里,函数可以对实参进行修改,从而影响全局变量

    例1:
    def f(x):     #形参
        print(x)
    
    f(3)    # 实参
    
    
    例2:
    import time
    times=time.strftime('%Y--%m--%d')
    
    def f(times):
        print('Now  time is : %s'%times)
    f(times)
    
    
    例3:
    def show_shopping_car():
        saving = 1000000
        shopping_car = [
            ('Mac', 9000),
            ('kindle', 800),
            ('tesla', 100000),
            ('Python book', 105),
        ]
        print('您已经购买的商品如下'.center(50, '*'))
        for i, v in enumerate(shopping_car, 1):
            print('%s:  %s' % (i, v))
    
        expense = 0
        for i in shopping_car:
            expense += i[1]
        print('
    您的余额为 %s' % (saving-expense))
    
    show_shopping_car()
    '''
    ********************您已经购买的商品如下********************
    1:  ('Mac', 9000)
    2:  ('kindle', 800)
    3:  ('tesla', 100000)
    4:  ('Python book', 105)
    
    您的余额为 890095
    '''
    1:形参和实参例子
    def action1(n):
        print('starting action1...')
    
        with open('日志记录', 'a') as f:
            f.write('end action%s
    ' % n)
    
    
    def action2(n):
        print('starting action2...')
    
        with open('日志记录', 'a') as f:
            f.write('end action%s
    ' % n)
    
    
    def action3(n):
        print('starting action3...')
    
        with open('日志记录', 'a') as f:
            f.write('end action%s
    ' % n)
    
    
    action1(1)
    action2(2)
    action3(3)
    '''
    starting action1...
    starting action2...
    starting action3...
    
    打开文件查看
    end action1
    end action2
    end action3
    '''
    
    
    # ***************代码重用
    # 上面发现每个函数都有打开文件,写内容的重复代码,把这些代码提取出来
    def logger(n):
        with open('日志记录', 'a') as f:
            f.write('end action%s
    ' % n)
    
    
    def action1():
        print('starting action1...')
        logger(1)
    
    
    def action2():
        print('starting action2...')
        logger(2)
    
    
    def action3():
        print('starting action3...')
        logger(3)
    
    
    action1()
    action2()
    action3()
    '''
    starting action1...
    starting action2...
    starting action3...
    
    打开文件查看
    end action1
    end action2
    end action3
    '''
    
    # ***************可扩展和保持一致
    # 再不改变各个 action 函数内部的前提下额外为日志加上时间
    import time
    
    def logger(n):
        time_format = '%Y-%m-%d %X'
        time_current = time.strftime(time_format)
    
        with open('日志记录', 'a') as f:
            f.write('%s end action%s
    ' % (time_current, n))
    
    
    def action1():
        print('starting action1...')
        logger(1)
    
    
    def action2():
        print('starting action2...')
        logger(2)
    
    
    def action3():
        print('starting action3...')
        logger(3)
    
    
    action1()
    action2()
    action3()
    
    '''
    starting action1...
    starting action2...
    starting action3...
    
    打开文件查看
    2018-05-02 12:03:39 end action1
    2018-05-02 12:03:39 end action2
    2018-05-02 12:03:39 end action3
    '''
    2:一个例子来说明函数的三个特性


    b、位置参数(必备参数)

    位置参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

    def f(name, age):
        print('I am %s,I am %d' % (name, age))
    
    f('alex', 18)
    f('alvin', 16)   # 位置参数,按函数提供的顺序,传递参数
    
    '''
    I am alex,I am 18
    I am alvin,I am 16
    '''


    c、关键字参数(实参参数)

    关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

    def f(name, age):
        print('I am %s,I am %d' % (name, age))
    
    # f(16, 'alvin')  # 报错:TypeError: %d format: a number is required, not str
    f(age=16, name='alvin')  # 关键字参数,指定 age 和 name 的值
    
    '''
    I am alvin,I am 16
    '''


    d、缺省参数(默认参数)

    调用函数时,缺省参数的值如果没有传入,则被认为是默认值。下例如果sex没有被传入,会打印默认的sex。

    默认参数一定要放在位置参数后面

    def print_info(name, age, sex='male'):    # 性别的默认值为 male,下面传递的时候可以改
        print('Name:%s' % name)
        print('age:%s' % age)
        print('Sex:%s' % sex)
    
    print_info('hjc', 24, 'fmale')     # 上面定义的 male ,这里传递参数可以改
    print_info('hjc', 24)  # 没有传递 sex 的参数,默认会显示 sex 的默认值
    '''
    Name:hjc
    age:24
    Sex:fmale
    
    Name:hjc
    age:24
    Sex:male
    '''


    e、不定长参数

    你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。

    *args
    def add(*args): # args 内部是一个元祖
        sum = 0
        for v in args:
            sum += v
        return sum
    
    print(add(1, 4, 6, 9))   # 20
    print(add(1, 4, 6, 9, 5))  # 25
    
    加了星号*)的变量名会存放所有未命名的变量参数(值)。而加(**)的变量名会存放命名的变量参数(键值)
    
    **kwargs
    def print_info(**kwargs):  # kwargs 内部是一个字典
        for i in kwargs:
            print('%s:%s' % (i, kwargs[i]))  # 根据参数可以打印任意相关信息了
        return
    
    print_info(name='alex', age=18, sex='female', hobby='girl',nationality='Chinese', ability='Python')
    '''
    name:alex
    age:18
    sex:female
    hobby:girl
    nationality:Chinese
    ability:Python
    '''

    不定长参数位置说明

    关于不定长参数的位置:*args 放在左边,**kwargs 参数放在右边

    def info(*args, **kwargs):  # 位置固定死了,反过来会报错
        print('args:', args)
        print('kwargs:', kwargs)
        for i in kwargs:
            print('%s:%s' % (i, kwargs[i]))
    
    
    info('hjc', 24, 'male', job='IT', hobby='girls', height=100)
    '''
    args: ('hjc', 24, 'male')
    kwargs: {'job': 'IT', 'hobby': 'girls', 'height': 100}
    job:IT
    hobby:girls
    height:100
    '''
    
    
    # def print_info(name,**kwargs,*args):报错
    def print_info(name, *args, **kwargs):
        print('Name:%s' % name)
        print('args:', args)
        print('kwargs:', kwargs)
    
    
    print_info('alex', 18, hobby='girl', nationality='Chinese', ability='Python')
    '''
    Name:alex
    args: (18,)
    kwargs: {'hobby': 'girl', 'nationality': 'Chinese', 'ability': 'Python'}
    '''
    
    # print_info(hobby='girl', 'alex', 18, nationality='Chinese', ability='Python')  # 报错
    # print_info('alex', hobby='girl', 18, nationality='Chinese', ability='Python')  # 报错

    注意,还可以这样传参:

    *args 相当于位置参数

    **kwargs 相当于关键字参数

    *args
    def f(*args):
        print(args)
    
    f(*[1, 2, 5]) # 传递一个列表,(1, 2, 5)
    f(*(1, 2, 5)) # 传递一个元组(1, 2, 5)
    

    **kwargs
    
    方式1:
    def f(**kargs):
        print(kargs)
    
    f(**{'name': 'alex'})  # {'name': 'alex'}
    
    方式2:
    def f2(**kwargs):
        print(kwargs)
    
    f2(info={'name': 'alex'})  # {'info': {'name': 'alex'}}


    8、高阶函数

    高阶函数是至少满足下列一个条件的函数:

    1、接受一个或多个函数作为输入,也就是把函数名作为参数输入

    2、函数名可以作为返回值

    例1:
    def add(x, y, f):
        return f(x) + f(y)
    
    res = add(3, -6, abs)  # abs 函数作为参数传递
    print(res)
    

    
    例2:
    def foo():
        x = 3
        def bar():
            return x
        return bar  # 返回函数名:一个内存地址,也是函数的本质
    
    print(foo)
    print(foo())
    

    
    例3:
    def f(n):
        return n*n
    
    def foo4(a, b, func):
        ret = func(a)+func(b)
        return ret
    
    print(foo4(1, 2, f))
    '''
    解释:
    先定义一个函数 f,函数 f 的对象是 n*n
    定义 foo4 函数,形参是(a,b,func)
    print(foo4(1,2,f))
    这里的 f,作为 foo4 的形参,func 调用函数 f,f(a)=f(1*1)=1,f(b)=f(2*2)=4
    ret=1+4
    '''


    9、函数返回值

    要想获取函数的执行结果,就可以用return语句把结果返回

    注意:

    1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
    2. 如果未在函数中指定return,那这个函数的返回值为None
    3. return 多个对象,解释器会把这多个对象组装成一个元组作为一个整体结果输出。可以通过变量压缩去取元组中的值
    4. 通常无参函数不需要给 return 返回值
    5. return 只有一个对象,返回的就是这个对象
    6. 变量压缩:tuple=(1,2,3)————a,b,c=(1,2,3)
    def f():
        print('ok')
        return True # 作用:1:结束函数;2:返回某个对象
    
    f()
    
    def foo():
        return 1,'alex',8 
    
    print(foo()) # (1, 'alex', 8),多个对象组装成一个元组,可以用多个变量去接收

    .

  • 相关阅读:
    Qt5信号与槽新写法
    Qt获取当前时间
    奇妙的enum class,enum struct组合
    vs2010+qt4编译出现error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject等错误
    QTreewidget的使用
    Qt各版本,VS插件下载地址
    Qt按钮设置透明
    Qt全局坐标和相对坐标
    QTableWidget
    c++11中thread join和detach的区别
  • 原文地址:https://www.cnblogs.com/tootooman/p/8979422.html
Copyright © 2020-2023  润新知