函数参数详解

一,什么是函数

如果在开发程序时 ,需要某块代码块多次执行。

为了提高编写的效率以及更好去维护代码,需要把具有独立功能的代码组织成一个小模块,这个就是函数

  1. 函数的格式

def 函数名字():
	运行代码

  1. 定义了函数之后,就相当于他有了一个具有某些功能的代码,想让这些代码能去执行,我们就需要去调用他
  2. 函数被定义之后是不会自动的去执行,需要我们自己去调用它
  3. 如果需要执行函数体里面的代码,我们就需要去手动调用函数
  4. 需要主义的是,我们每次调用函数都会让他从头开始,当这个函数中的代码执行完毕之后,就意味着调用结束了。
  5. 如果在函数执行的过程中,函数碰到了 return 那么他也会结束函数
  • 接下来是示例代码
def sums():
    print('666')
#函数调用好了不会自动去执行 而是需要去调用
sums()

def tell_story():
    print('从前有座山')
    print('山上有座庙')
    print('庙里有个老和尚')
    print('还有个小和尚')
    print('老和尚在给小和尚讲故事')
    print('故事的内容是:')


age = int(input('请输入孩子的年龄'))
if  0<=age<=3:
    for x in range(5):
        tell_story()
elif 3<age<=5:
    tell_story()


def tell_story():
    return '从前有座山'+'山上有座庙'+'庙里有个老和尚'+'还有个小和尚'+'老和尚在给小和尚讲故事'+'故事的内容是:'

print(tell_story())

二,函数的参数

  • 说完了函数,接下来就是函数的参数。

  • 为了让一个函数更通用,即想让它计算哪两个数的和,就让它计算哪两个数的和,在定义函数的时候可以让函数接收数据,就解决了这个问题,这就是 函数的参数

1)定义,调用带有参数的函数

定义一个add2num(a, b)函数,来计算任意两个数字之和:

def add2num(a, b):
    c = a+b
    print c

add2num(11, 22) # 调用带有参数的函数时,需要在小括号中,传递数据
Copy

注意点:

  • 在定义函数的时候,小括号里写等待赋值的变量名
  • 在调用函数的时候,小括号里写真正要进行运算的数据
    #将实际参数返回到形式参数
def sums(num1,num2,num3):   #num1,num2,num3  统称为形式参数
    """
    这个函数是用来求三个函数的和
    :param num1:    #第一个数字
    :param num2:    #第二个数字
    :param num3:    #第三个数字
    :return:        #三个数字的和
    """
    return num1+num2+num3   #  return 返回参数

print(sums(100,200,300))   #统称为实际参数 
  • 这个地方的意思是,定义一个sums函数,并且定义了3个值

  • 所以在我们完成代码的时候需要将 sums中的3个值传进去,不然程序将会出现报错

  • 再来一个示例代码

    def tell_story(p1,p2):
        """
    
        :param p1:
        :param p2:
        :return:
        """
        print('从前有座山')
        print('山上有座庙')
        print('庙里有个'+p1)
        print('还有个'+p2)
        print(p1+'再给'+p2+'讲故事')
        print('故事的内容是')
    
    tell_story('老尼姑','小和尚')
    tell_story(p1='小和尚',p2='老尼姑')
    
  • 这里在最后面将 P1 P2 给定了值,所以他会按照给定的顺序来传值 如果,没有给定顺序,那么将会按着顺序传上去

接下来,做两个小练习

练习1,设计一个函数,传入的参数是一个列表,返回去掉列表中重复元素之后的列表。

提示,set集合可以去重

def remove_item(lists):     #定义一个参数
    """

    :param list2:
    :return:
    """
    return list(set(lists))   #返回函数
print(remove_item([1,2,3,1,1,3,5,6,8]))

练习2,设计一个函数,传入的参数是一个列表,返回去掉列表中重复元素之后的列表,列表中的元素需要保持原来的顺序。

def remove_itmel(lists):    #定义一个参数
    res=[]
    see = set()
    for li in lists:
        if li not in see:
            res.append(li)
            see.add(li)
    return res          #返回函数   如果返回的是res  将不会自动排序,如果返回的是see就会自动排序
print(remove_itmel([1,3,5,6,9,7,4,4,6,45,2,3]))
来几个简单的代码,好理解一下
def hengxian():
    """

    :return:
    """
    return ("-"*30)	#返回的东西是 (=*30)
print(hengxian())	#然后输出



def huaxian(a):
    for x in range(0,a):
        print( '-'*10)
        return a

print(int(input('定义行数')))	





def fact(num):
    x = 1
    for res in range(1, num+1):
        x*= res
    return x
print(fact(6))

在函数中,有一个全局变量 还有一个局部变量

但是if for while这些语句都不存在全局变量这一说

kangbazi = '123'

def tses():
    global kangbazi
    kangbazi= '654'
    print(kangbazi)

def test():
    print(kangbazi)

tses()  #声明调用
test()

if for while   都不存在全局变量这一说
if 4>3:
    m = 'test'
print(m)

for x in range(0,2):

三,函数的返回值

一、“返回值”介绍

现实生活中的场景:

我给儿子10块钱,让他给我买个冰淇淋。这个例子中,10块钱是我给儿子的,就相当于调用函数时传递到参数,让儿子买冰淇淋这个事情最终的目标,我需要让他把冰淇淋带回来,此时冰淇淋就是返回值

开发中的场景:

定义了一个函数,完成了获取室内温度,想一想是不是应该把这个结果给调用者,只有调用者拥有了这个返回值,才能够根据当前的温度做适当的调整

综上所述:

  • 所谓“返回值”,就是程序中函数完成一件事情后,最后给调用者的结果
  • 使用返回值的前提需求就是函数调用者想要在函数外使用计算结果

二、带有返回值的函数

想要在函数中把结果返回给调用者,需要在函数中使用return

如下示例:

def add2num(a, b):
    c = a+b
    return c  # return 后可以写变量名
Copy

或者

def add2num(a, b):
    return a+b  # return 后可以写计算表达式
Copy

三、保存函数的返回值

在本小节刚开始的时候,说过的“买冰淇淋”的例子中,最后儿子给你冰淇淋时,你一定是从儿子手中接过来 对么,程序也是如此,如果一个函数返回了一个数据,那么想要用这个数据,那么就需要保存

保存函数的返回值示例如下:

#定义函数
def add2num(a, b):
    return a+b

#调用函数,顺便保存函数的返回值
result = add2num(100,98)

#因为result已经保存了add2num的返回值,所以接下来就可以使用了
print(result)
Copy

结果:

198
小例子
def sums(a,b):
    """
    这是一个求和函数
    :param a:
    :param b:
    :return: 返回两个数的和
    """
    c = a+b
    return c

res = sums(b=10,a=100)
x = print(res ** 4) # print内置函数  不能报错它的结果
print(x) #None

y = input('请输入一个值')
print(y)

函数的文档注释

在函数写完了函数名和形式参数之后,可以在下面说明这个地方传的值是什么,使用的参数是那个

然后是重头戏

四,函数的调用

我直接用代码加注释来解释

ef sums(a,b):
    return a+b


def test(a,b,c):
    return a+sums(b,c)


res = test(10,20,30)
print(res)

#练习1:设计一个函数,传入的参数是一个列表,返回去掉列表中重复元素之后的列表。
def remove_item(lists):
    """
    给列表去重
    :param list: 参数是一个列表
    :return: 返回一个列表 去重以后的
    """
    return list(set(lists))

# print(remove_item([1,1,2,1,3,4,2,3]))

#练习2:设计一个函数,传入的参数是一个列表,返回去掉列表中重复元素之后的列表,列表中的元素需要保持原来的顺序。

def remove_item1(lists):
    res = []
    see = set()
    for li in lists:
        if li not in see:
            res.append(li)
            see.add(li)
    return res
print(remove_item1([8,1,4,2,1,3,4,2,3]))

函数的调用二

# 定义一个函数  求 [n,m)之间所有整数的和
# def add(n,m):
#     sums = 0
#     for x in range(n, m):
#         sums += x
#     return sums

# sums = 0
# for x in range(10,100):
#     sums+=x
# print(sums)

# print(add(10,100))

#求 n的阶乘  5的阶乘 1*2*3*4*5

def factorial(num):
    x = 1
    for res in range(1, num+1):
        x *= res
    return x
# print(factorial(5))

# x = 1
# for res in range(1,6):
#     x*=res
# print(x)

#求 n的 阶乘的和  以5为例子    1!+2!+3!+4!+5!
# res = 0
# for x in range(1,6):
#     res+=factorial(x)
# print(res)
# test = 100 #全局变量
# def factorial_sum(m):
#     haha = 666 #局部变量
#     res = 100
#     for x in range(1,m+1):
#         res+=factorial(x)
#     return res
#
# # print(factorial_sum(5))
# print(test)
# # print(haha) #报错  全局下不能打印局部的变量
  • 这样就引出了一个新的东西,就是全局变量和局部变量

五,全局变量 局部变量

kangbazi = 'wh2003'  #所有的函数都可以用


def test1():
    kangbazi = 999 #局部变量
    print(kangbazi) #如果自己的范围内有kangbazi 就调用该范围的  没有 调用全局的
    # print(haha)

def test2():
    print(kangbazi)
    # print(haha) #报错


test1()
test2()
  • 如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量
  • 打个比方:有2个兄弟 各自都有手机,各自有自己的小秘密在手机里,不让另外一方使用(可以理解为局部变量);但是家里的电话是2个兄弟都可以随便使用的(可以理解为全局变量)

  • 总结:

    • 在函数外边定义的变量叫做全局变量
    • 全局变量能够在所有的函数中进行访问

全局变量和局部变量名字相同问题

  • 当函数内出现局部变量和全局变量相同名字时,函数内部中的 变量名 = 数据 此时理解为定义了一个局部变量,而不是修改全局变量的值

修改全局变量

总结:

  • 如果在函数中出现global 全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名 = 数据 也理解为对全局变量进行修改,而不是定义局部变量
  • 如果在一个函数中需要对多个全局变量进行修改,那么可以一次性全部声明,也可以分开声明
# 可以使用一次global对多个全局变量进行声明
global a, b
# 还可以用多次global声明都是可以的
# global a
# global b

查看所有的全局变量和局部变量

Python提供了两个内置函数globals()和locals()可以用来查看所有的全局变量和局部变量。

def test():
    a = 100
    b = 40
    print(locals())  # {'a': 100, 'b': 40}

test()

x = 'good'
y = True
print(globals())  # {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x101710630>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': '/Users/jiangwei/Desktop/Test/test.py', '__cached__': None, 'test': , 'x': 'good', 'y': True}

修改多个全局变量

#
# kangbazi = 'whpy2003'
#
#
# def test():
#     # kangbazi = 'haha' #这个时候并不是说重新给全局变量kangbazi 重新赋值进行修改
#     # #而是声明了一个局部变量  只能在test里边使用的
#     # print(kangbazi) # haha
#     global kangbazi #声明kangbazi 是全局变量
#     kangbazi = 'wuhanpython2003'
#     print(kangbazi)
#
# def test1():
#     print(kangbazi)
# test()
# test1()

# words = '你好'
#
# def test():
#     x = 'hello'
#     global words
#     words = '你好,灭霸'
#     print('locals={},globals={}'.format(locals(),globals()))
#
# test()
# #locals={'x': 'hello'},globals={'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001BA37C2E788>, '__spec__': None, '__annotations__': {}, '__builtins__': , '__file__': 'C:/www/whpy03/day9/08修改全局变量.py', '__cached__': None, 'words': '你好', 'test': }
#
# print('函数的外部words={}'.format(words))
# # print('函数的内部x={}'.format(x)) #报错
#
# #locals() 内置函数  显示 当前区域内所有的局部变量
# #globals() 内置函数  显示当前 .py文件 全局变量


# if 4>3:
#     m = 'test'
#
# print(m)

# for x in  range(5):
#     haha = 'test'
#     print(x)
#
# print(haha)

# if for while 里边不存在什么全局变量 局部变量这一说

# i = 0
# while i<5:
#     test = 'hahahahahaah'
#     print(i)
#     i+=1
# print(test)

def kangbazi(str1,str2):
    """

    :param str1:
    :param str2:
    :return:
    """

要在函数内部修改全局变量必须使用global

六,多个返回值

一、多个return?

def create_nums():
    print("---1---")
    return 1  # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
    print("---2---")
    return 2
    print("---3---")

总结1:

  • 一个函数中可以有多个return语句,但是只要有一个return语句被执行到,那么这个函数就会结束了,因此后面的return没有什么用处

  • 如果程序设计为如下,是可以的因为不同的场景下执行不同的return

      def create_nums(num):
          print("---1---")
          if num == 100:
              print("---2---")
              return num+1  # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
          else:
              print("---3---")
              return num+2
          print("---4---")
    
      result1 = create_nums(100)
      print(result1)  # 打印101
      result2 = create_nums(200)
      print(result2)  # 打印202
    
    

二、一个函数返回多个数据的方式

def divid(a, b):
    shang = a//b
    yushu = a%b 
    return shang, yushu  #默认是元组

result = divid(5, 2)
print(result)  # 输出(2, 1)
Copy
def calculate(num1,num2):
    """

    :param num1:
    :param num2:
    :return:
    """
    x = num1 + num2
    y = num1 - num2
    z = num1 * num2
    h = num1 / num2
    return x,y,z,h # 本质返回的是一个元组
    # return {'x':x,'y':y,'z':z,'h':h}
    # return [x,y,z,h]
# print(calculate(1,2)) #(3, -1, 2, 0.5)
# res = calculate(1,2)
# print(res[0])

he,cha,ji,shang = calculate(1,2)
print(he,cha,ji,shang)

总结2:

  • return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据。

          def function():
              # return [1, 2, 3]
              # return (1, 2, 3)
              return {
           "num1": 1, "num2": 2, "num3": 3}
    Copy
    
  • 如果return后面有多个数据,那么默认是元组。

对返回的数据直接拆包

def get_my_info():
    high = 178
    weight = 100
    age = 18
    return high, weight, age  # 函数返回三个数据,会自动打包为元组

# result = get_my_info()  # result 接收到一个元组
# print(result)

my_high, my_weight, my_age = get_my_info()  # 直接把元组拆分为三个变量来使用,更加方便
print(my_high)
print(my_weight)
print(my_age)
Copy

总结:

  • 拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
  • 除了对元组拆包之外,还可以对列表、字典等拆包

七,函数参数详解

一、缺省参数

调用函数时,缺省参数的值如果没有传入,则取默认值。

下例会打印默认的age,如果age没有被传入:

def printinfo(name, age=35):
   # 打印任何传入的字符串
   print("name: %s" % name)
   print("age %d" % age)

# 调用printinfo函数
printinfo(name="miki")  # 在函数执行过程中 age取默认值35
printinfo(age=9 ,name="miki")
Copy

以上实例输出结果:

name: miki
age: 35
name: miki
age: 9
Copy

总结:

  • 在形参中默认有值的参数,称之为缺省参数

  • 注意:带有默认值的参数一定要位于参数列表的最后面

      >>> def printinfo(name, age=35, sex):
      ...     print name
      ...
        File "", line 1
      SyntaxError: non-default argument follows default argument
    Copy
    

二、不定长参数

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

基本语法如下:

def functionname([formal_args,] *args, **kwargs):
   """函数_文档字符串"""
   function_suite
   return [expression]
Copy

注意:

  • 加了星号(*)的变量args会存放所有未命名的变量参数,args为元组
  • 而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典.
def test(a, b, *args, **kwargs):
      "函数在声明时,需要两个参数"
    print('a={},b={},args={},kwargs={}'.format(a,b,args,kwargs))

test(2, 3, '你好', 'hi', 'how do you do', name="zhangsan", age=18)
# a=2,b=3,args=('你好', 'hi', 'how do you do'),kwargs={'name': 'zhangsan', 'age': 18}


b = ('hi', '大家好', '今天天气真好')
d = {
     'name': "zhangsan", "age": 19}

# 注意,在传入参数时的星号问题。
test(10, 20, *b, **d) 
# a=10,b=20,args=('hi', '大家好', '今天天气真好'),kwargs={'name': 'zhangsan', 'age': 19}


# 如果在传值时,不使用星号,会把后面的参数当做 args
test(10,20,b,d)
# a=10,b=20,args=(('hi', '大家好', '今天天气真好'), {'name': 'zhangsan', 'age': 19}),kwargs={}
Copy

三、缺省参数在*args后面

def sum_nums_3(a, *args, b=22, c=33, **kwargs):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)

sum_nums_3(100, 200, 300, 400, 500, 600, 700, b=1, c=2, mm=800, nn=900)
Copy

说明:

  • 如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有**kwargs的话,**kwargs必须是最后的

你可能感兴趣的:(Python,python)