zoukankan      html  css  js  c++  java
  • Python基础-函数

    函数基本使用

    python中定义函数所用的关键字是def, def 函数名() : 冒号代替其他编程语言的大括号,然后换行缩进写的代码就是函数体。

    def welcome():
        '''
        一个简单的函数
        :return:
        '''
        print("Hello World !")
    
    
    welcome()

    打印结果:

    Hello World !

    三引号中间的内容属于函数的注释文档,在实际项目中都尽量要把每个函数的文档注释写好,在这里为了节约篇幅,本文下面的代码示例就不再添加这个注释了。

    函数还可以嵌套,也就是函数里面有函数:

    def welcome(name):
        def go(name):
            print('我最棒:' + name)
        go(name)
    
    welcome('小明')

    打印结果:

    我最棒:小明

    函数的参数

    形参和实参

    def welcome(username):
        print("Hello World ! My name is " + str(username))
    
    welcome("小明")
    welcome("小花")

    打印结果:

    Hello World ! My name is 小明
    Hello World ! My name is 小花

    这是一个带参数的函数,在函数welcome中,username就是一个形参,也就是形式参数,是用来接收调用函数时传入的参数,你传的是啥它就是啥,传人它就是人,传鬼它就是鬼的那种。

    实参就是实际参数,在调用函数的时候,传递是小明,那么小明就是实参,传递的是小花,那么小花也是实参,实参传递给函数后,会赋值给函数中的形参,然后我们就可以在函数中使用到外部传入的数据了。

    参数默认值

    写Java的时候最痛恨的就是方法不能设置默认值,使得必须得重载才行。

    python允许我们给函数的形参设置一个默认值,不传参数调用的话,就统一默认是这个值。

    def welcome(username = '奥特曼'):
        print("Hello World ! My name is " + str(username))
    
    welcome("小明")
    welcome()

    打印结果:

    Hello World ! My name is 小明
    Hello World ! My name is 奥特曼

    修改参数后影响外部

    在函数中修改参数内容会不会影响到外部,这个问题取决于实参的类型是不是可变的,可不可变就是可不可以修改。

    字符串就是一种不可变的类型。

    比如:

    name = "小明"
    name = "小花"

    请问,我是把"小明"修改成了"小花"吗? 答案是 非也。

    实际上我是把"小花"这个字符串赋值给了name,让name指向了这个新字符串,替换掉了原来的"小明",原来的"小明"仍然是"小明",没有受到一点改变。

    在python中,不可变类型有:整数、字符串、元组,可变类型有:列表、字典。如果传递的参数包含可变类型,并且在函数中对参数进行了修改,那么就会影响到外部的值

    def change(lis):
        lis[1] = '小明他大爷'
    
    names = ['小明','小花','小红']
    change(names)
    print(names)

    打印结果:

    ['小明', '小明他大爷', '小红']

    如果我们不希望出现这种事情,那么就将对象复制一份再传递给函数。

    def change(lis):
        lis[1] = '小明他大爷'
    
    names = ['小明','小花','小红']
    change(names[:])
    print(names)

    打印结果:

    ['小明', '小花', '小红']

    我们用切片的方法拷贝了一份names,函数中尽管修改了参数,也不过是修改的是副本,不会影响到原始的names。

    关键字参数

    关键字参数让你可以不用考虑函数的参数位置,你需以键值对的形式指定参数的对应形参。

    def welcome(name,address):
        print(f"你好 {name} , 欢迎来到 {address} !")
    
    welcome(address='上海',name='小强')

    打印结果:

    你好 小强 , 欢迎来到 上海 !

    收集参数

    有时候我们需要允许用户提供任意数量的参数,函数的形参可以带个星号来接收,不管调用函数的时候传递了多少实参,都将被收集到形参这个变量当中,形参的类型是元组。

    def welcome(*names):
        print(names)
    
    welcome('小明','小强','小红','小黑')

    打印结果:

    ('小明', '小强', '小红', '小黑')

    还有一种是带两个星号的形参,用于接收键值对形式的实参,导入到函数中的类型是字典。

    def welcome(**names):
        print(names)
    
    welcome(name='小明',age=18,sex='')

    打印结果:

    {'name': '小明', 'age': 18, 'sex': '男'}

    分配参数

    分配参数是收集参数的相反操作,可使得一个元组或字典变量自动分配给函数中的形参。

    def welcome(name,address):
        print(f"你好 {name} , 欢迎来到 {address} !")
    
    a = ('小红','山东')
    welcome(*a)

    打印结果:

    你好 小红 , 欢迎来到 山东 !

    我们改成字典的方式:

    def welcome(name,address):
        print(f"你好 {name} , 欢迎来到 {address} !")
    
    a = {'address':'山东','name':'小红'}
    welcome(**a)

    打印结果:

    你好 小红 , 欢迎来到 山东 !

    函数的返回值

    首先说明,所有的函数都是有返回值的,如果编程人员没有指定返回值,那么默认会返回None,对标其他语言中的null

    一个简单的函数返回值的例子:

    def get_full_name(first_name,last_name):
        return first_name + last_name
    
    r = get_full_name('','大锤')
    print(r)

    打印结果:

    王大锤

    然而python中的函数还可以返回多个值,返回出的值被装载到元组中:

    def func(num):
        return num**2,num**3,num**4
    
    result = func(2)
    print(result)

    打印结果:

    (4, 8, 16)

    在python中函数定义的时候没有返回值的签名,导致我们无法提前知道函数的返回值是什么类型,返回的什么完全看函数中的return的是什么,特别是逻辑代码比较多的函数,比如里面有多个if判断,有可能这个判断return出来的是布尔值,另一个判断return出来的是列表,还一个判断啥也不return,你调用的时候你都搞不清楚该怎么处理这个函数的返回值,在这一点来说,Java完胜。

    所以在无规则限制的情况下,代码写的健不健壮,好不好用,主要取决于编程人员的素质。

    匿名函数

    匿名函数就是不用走正常函数定义的流程,可以直接定义一个简单的函数并把函数本身赋值给一个变量,使得这个变量可以像函数一样被调用,在python中可以用lambda关键字来申明定义一个匿名函数。

    我们把王大锤的例子改一下:

    get_full_name = lambda first_name,last_name : first_name + last_name
    r = get_full_name('','大锤')
    print(r)

    打印结果:

    王大锤

    函数的作用域

    访问全局作用域

    python每调用一个函数,都会创建一个新命名空间,也就是局部命名空间,函数中的变量就叫做局部变量,与外部的全局命名空间不会相互干扰。

    这是常规状态,当然也会有非常规需求的时候,所以python给我们提供了globals()函数,让我们可以在局部作用域中访问到全局的变量。

    def func():
        a = globals()
        print(a['name'])
    
    name = '小明'
    func()

    打印结果:

    小明

    globals()函数只能让我们访问到全局变量,但是是无法进行修改的,如果我们要修改全局变量,需要用到global关键字将全局变量引入进来。

    def func():
        global name
        name = '小花'
    
    name = '小明'
    func()
    print(name)

    打印结果:

    小花

    访问嵌套作用域

    对于嵌套函数的情况,如果想要使用嵌套作用域(非全局作用域)的变量,就需要用到nonlocal关键字。

    def welcome(name):
        def go():
            nonlocal name
            name = '我变成小花了'
        go()
        print(name)
    
    my_name = '小明'
    welcome(my_name)
    print(my_name)

    打印结果:

    我变成小花了
    小明

    函数与模块

    导入模块

    模块的官方定义是包含函数和变量的python文件就叫做模块,然而你照着这个定义去看,你会发现只要是.py的文件,其实都符合模块的定义。

    我新建一个user.py文件 他也叫做user模块 里面写两个函数

    def get_name():
        print('我的名字是小明')
    
    def get_age():
        print('我今年11岁了')

    然后我用import导入这个user模块 并调用模块中的函数

    import user
    user.get_name()

    打印结果:

    我的名字是小明

    这个用处相当于公共函数的封装,当然了,我们面向对象的做法一般都是封装到类里面。

    为了防止模块名字被当前程序的变量覆盖,你可以选择导入的时候用as指定别名:

    import user as model_user
    model_user.get_name()

    打印结果:

    我的名字是小明

    导入函数

    还是拿上面user模块来做例子  我现在只导入其中某个函数

    from user import get_name
    get_name()

    打印结果:

    我的名字是小明

    from ... import ... 的意思就是 从...中获取...,从user模块中获取get_name函数。

    导入模块中所有函数

    通配符星号表示导入所有函数,只是这种做法,有大几率出现函数被覆盖的风险

    from user import *
    get_name()
    get_age()

    打印结果:

    我的名字是小明
    我今年11岁了

  • 相关阅读:
    codevs 1766 装果子
    codevs 1415 比那名居天子
    codevs 1388 砍树
    codevs 1373 射命丸文
    codevs 2867 天平系统3
    codevs 2866 天平系统2
    codevs 2865 天平系统1
    codevs 2832 6个朋友
    广搜优化题目总结
    Codeforces Round #578 (Div. 2)
  • 原文地址:https://www.cnblogs.com/fengyumeng/p/13266312.html
Copyright © 2011-2022 走看看