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

    函数

    函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

    函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

    1、定义一个函数

    你可以定义一个由自己想要功能的函数,以下是简单的规则:

    • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
    • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
    • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
    • 函数内容以冒号起始,并且缩进。
    • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
    def test():
        """
          for test
        """
        print("in the test funcation")
        return 0
    
    # def  定义函数的关键字
    # test 函数名(函数标识名称符)
    # ()  任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数
    #  """for test"""  函数说明,说明函数作用,方便他人阅读代码
    # print("in the test funcation") 函数体(代码块),注意缩进
    #  return 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None

    2、函数特征:

    • 代码重复利用
    • 可扩展性
    • 保持一致性

    优化前:

     1 # 打印字符串
     2 print("ABCD")
     3 print("EFGH")
     4 
     5 
     6 # 现在下面有2个函数,每个函数处理完了,都需要使用上面的逻辑,那么唯一的方法就是拷贝2次这样的逻辑
     7 
     8 def test_1():
     9     "test"
    10     print("in the test1")
    11     print("ABCD")
    12     print("EFGH")
    13 
    14 
    15 def test_2():
    16     "test"
    17     print("in the test2")
    18     print("ABCD")
    19     print("EFGH")
    View Code

    优化后:

     1 # 新定义一个函数
     2 def test():
     3     """test"""
     4     print("ABCD")
     5     print("EFGH")
     6 
     7 
     8 # 在想执行打印字符串功能的函数中,调用test()函数就可以了
     9 def test_1():
    10     """test"""
    11     print("in the test1")
    12 test()  # 调用test()函数
    13 
    14 def test_2():
    15     """test"""
    16     print("in the test2")
    17 test()  # 调用test()函数
    View Code

    3、定义函数的三种形式

    1、无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印

    2、有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值

    3、空函数:设计代码结构

     1 #定义阶段
     2 def tell_tag(tag,n): #有参数
     3     print(tag*n)
     4 
     5 def tell_msg(): #无参数
     6     print('hello world')
     7 
     8 #调用阶段
     9 tell_tag('*',12)
    10 tell_msg()
    11 tell_tag('*',12)
    12 
    13 '''
    14 ************
    15 hello world
    16 ************
    17 '''
    18 
    19 #结论:
    20 #1、定义时无参,意味着调用时也无需传入参数
    21 #2、定义时有参,意味着调用时则必须传入参数
    无参、有参
     1 def auth(user,password):                             
     2     '''                                                           
     3     auth function                                                 
     4     :param user: 用户名                                              
     5     :param password: 密码                                           
     6     :return: 认证结果                                                 
     7     '''                                                           
     8     pass                                                          
     9                                                                   
    10 def get(filename):                                                
    11     '''                                                           
    12     :param filename:                                              
    13     :return:                                                      
    14     '''                                                           
    15     pass                                                          
    16                                                                   
    17 def put(filename):                                                
    18     '''                                                           
    19     :param filename:                                              
    20     :return:                                                      
    21     '''                                                           
    22 def ls(dirname):                                                  
    23     '''                                                           
    24     :param dirname:                                               
    25     :return:                                                      
    26     '''                                                           
    27     pass                                                          
    28 
    29 #程序的体系结构立见 
    空函数

    4、函数的参数:

    • 形参:指的是形式参数,是虚拟的,不占用内存空间,形参单元只有被调用的时才分配内存单元
    • 实参:指的是实际参数,是一个变量,占用内存空间,数据传递单向,实参传给形参,形参不能传给实参
    def test(x,y): #x,y是形参
        print(x)
        print(y)
     
    test(1,2) #1和2是实参
    #输出
    1
    2

    4.1、位置参数

    从上面的例子可以看出,实际参数和形式参数是一一对应的,如果调换位置,x和y被调用的时,位置也会互换,代码如下
    def test(x,y):
        print(x)
        print(y)
    print("--------互换前-----")
    test(1,2)
    print("--------互换后-----")
    test(2,1)
     
    #输出
    --------互换前-----
    1
    2
    --------互换后-----
    2
    1
    因为定义x,y两个形参,所以传递实参的时候,也只能传递两个实参,多一个或少一个都是有问题的:
     1 #多传递一个参数
     2 def test(x, y):
     3     print(x)
     4     print(y)
     5 
     6 
     7 print("--------多一个参数----")
     8 test(1,2,3)
     9 
    10 #输出结果
    11 Traceback (most recent call last):
    12 --------多一个参数----
    13     test(1,2,3)
    14 TypeError: test() takes 2 positional arguments but 3 were given  #test()函数需要传两个实参,你传了三个实参
    15 
    16 
    17 
    18 #少传递一个实参
    19 def test(x, y):
    20     print(x)
    21     print(y)
    22 
    23 
    24 print("--------少一个参数----")
    25 test(1)
    26 
    27 #输出结果
    28 --------少一个参数----
    29 Traceback (most recent call last):
    30     test(1)
    31 TypeError: test() missing 1 required positional argument: 'y'  #没有给y参数传实参
    View Code

    4.2关键字参数

    上面的位置参数,看起来有点死,必须形参和实参的位置一一对应,不然就会传错参数,为了避免这种问题,就有了关键字参数的玩法:关键字传参不需要一一对应,只需要你指定你的哪个形参调用哪一个实参即可;
    def test(x,y):
        print(x)
        print(y)
     
    print("--------互换前------")
    test(x=1,y=2)
    print("--------互换后------")
    test(y=2,x=1)
     
    #输出
    --------互换前------
    1
    2
    --------互换后------
    1
    2

    位置参数和关键字参数结合使用:

    1.位置参数在前,关键字参数在后

    def test(x,y):
        print(x)
        print(y)
     
    test(1,y=2)
     
    #输出
    1
    2
    def test(x,y,z):
        print(x)
        print(y)
        print(z)
     
    test(1,z=2,y=3)
     
    #输出
    1
    3
    2

    2.上面的列子是关键字传参传给y,现在传给x,代码如下:

    def test(x,y):
        print(x)
        print(y)
     
    test(1,x=2)
     
    #输出结果
    Traceback (most recent call last):
        test(1,x=2)
    TypeError: test() got multiple values for argument 'x' #给x形参传的值过多,之前位置参数 就传实参给x一次,后面关键字又传实参给x,造成报错

    3.关键字参数在前,位置参数在后:

    def test(x,y):
        print(x)
        print(y)
     
    test(y=2,1)
    
    #输出结果
        test(y=2,1)
                ^
    SyntaxError: positional argument follows keyword argument  # 关键字参数在位置参数的前面

    4.关键字参数在中间:

    def test(x,y,z):
        print(x)
        print(y)
     
    test(1,y=2,3)
    
    #输出结果
        test(1,y=2,1)
                  ^
    SyntaxError: positional argument follows keyword argument 

    结论:关键字参数是不能写在位置参数前面的。

    5、全局变量和局部变量

    5.1、局部变量

    局部变量:顾名思义,指在局部生效,定义在函数体内的变量只能在函数里面生效,出个这个函数体,就不能找到它,这个函数就是这个变量的作用域,如下代码:

    name = "apple"
    
    def test(name):
        print("before change:",name)
        name = "bananan"  #局部变量name,只能在这个函数内生效,这个函数就是这个变量的作用域
        print("after change:",name)
     
    
    
    test(name)
    print(name)
     
    #输出结果
    before change: apple
    after change: bananan  #局部变量生效
    
    bananan# 外部的变量还是apple,仅函数内的name变成了bananan

    5.2、全局变量

    全局变量:指的是在整个程序中都生效的变量,在整个代码的顶层声明:

    name = "apple"
    
    
    def test(name):
        print("before change:", name)
        name = "bananan"  # 局部变量name,只能在这个函数内生效,这个函数就是这个变量的作用域
        print("after change:", name)
    
    
    def test1(name):
        print(name)
    
    
    test(name)
    test1(name)
    print(name)
    
    #输出结果
    before change: apple
    after change: bananan  #局部变量生效
    
    apple# 全局变量
    apple# 全局变量

    注:全局变量的优先级是低于局部变量的,当函数体内没有局部变量,才会去找全局变量

    5.3、局部变量改成全局变量

    • 改前用global先声明一下全局变量
    • 将全局变量重新赋值
    name1 = "apple"
    
    
    def test(name):
        global name1  # 使用global 声明全局变量
        print("before change:", name1)
        name1 = "bananan"  # 全局变量重新赋值
        print("after change:", name1)
    
    
    def test1(name1):
        print(name1)
        
    test(name1)
    test1(name1)
    print(name1)
    
    #输出结果
    before change: apple
    after change: bananan  
    
    bananan
    bannann

    注:最好不要用global这个关键字,因为你用了,其他人调你的函数时,就乱套了,而且还不好调试。

    5.4、全局变量定义成列表

    names = ['AAAA',"BBBB"]  #定义一个列表
     
    def test():
        names[0] = "CCCC"
        print(names)
     
    print("--------test-----")
    test()
    print("------打印names--")
    print(names)
     
    #输出结果
    --------test-----
    ['CCCC', 'BBBB']     #函数内的names输出
    ------打印names--
    ['CCCC', 'BBBB']     #函数外的names输出

    注:1、只有字符串和整数是不可以被修改的,如果修改,需要在函数里面声明global。2、但是复杂的数据类型,像列表(list)、字典(dict)、集合(set)、类(class)都是可以修改的。

    5.5、小实验: 

    局部作用域和全局作用域的访问顺序

    #局部作用域和全局作用域的访问顺序
    x=0
    def grandpa():
        x=1
        def dad():
            x=2
            def son():
                x=3
                print(x)
            son()
        dad()
    #调用grandpa
    grandpa()
     
    #输出结果
    3

    注:作用域,只能是从里往外找,一层一层的的找。

    全局变量和局部变量小结:

    1. 在子程序(函数)中定义的变量称为局部变量,在程序一开始定义的变量称为全局变量。
    2. 全局变量的作用域是整个程序,局部变量的作用域是定义该变量的子程序(函数)。
    3. 当全局变量和局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其他地方,全局变量起作用。
  • 相关阅读:
    4.父类私有属性和方法
    3.单继承和方法的重写
    2.Python封装练习及私有属性
    1.Python面向对象基础
    6.类与对象、封装、构造方法
    5.数组
    4.方法
    3.流程控制语句
    结构型模式和物理视图,模型管理试图的总结
    创建型模式和关于状态视图、活动视图、交互视图的总结
  • 原文地址:https://www.cnblogs.com/doumingyi/p/12450071.html
Copyright © 2011-2022 走看看