函数 初识

---恢复内容开始---

Python 函数

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

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

 1 定义一个函数

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

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

 2  return关键字的作用

  return 是一个关键字,在pycharm里,你会看到它变成蓝色了。你必须一字不差的把这个单词给背下来。

  这个词翻译过来就是“返回”,所以我们管写在return后面的值叫“返回值”

要研究返回值,我们还要知道返回值有几种情况:分别是没有返回值、返回一个值、返回多个值

没有返回值

  不写return的情况下,会默认返回一个None:我们写的第一个函数,就没有写return,这就是没有返回值的一种情况. 刚刚我们已经写过一个返回一个值的情况,只需在return后面写上要返回的内容即可。也可以返回任意多个、任意数据类型的值,返回的多个值会被组织成元组被返回,也可以用多个值来接收

只写return,后面不写其他内容,也会返回None,有的同学会奇怪,既然没有要返回的值,完全可以不写return,为什么还要写个return呢?这里我们要说一下return的其他用法,就是一旦遇到return,结束整个函数

def ret_demo():
    print(111)
    return
    print(222)

ret = ret_demo()
print(ret)

只写return

结果:

多个值接收

def ret_demo2():
    return 1,['a','b'],3,4

#返回多个值,用一个变量接收
ret2 = ret_demo2()
print(ret2)

#返回多个值,用多个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)

#用多个值接收返回值:返回几个值,就用几个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)

多个返回值的接收

多个值接收

结果:

  3 参数

可更改(mutable)与不可更改(immutable)对象

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

  • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。

  • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

python 函数的参数传递:

  • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

  • 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

参数

以下是调用函数时可使用的正式参数类型:

  • 位置参数
  • 关键字参数
  • 默认参数
  • 混合参数

位置参数

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

调用printme()函数,你必须传入一个参数,不然会出现语法错误:

s = 'fdsafsda'
l2 = [1, 2, 3, 4, 5, 6, 5, 4, 3, 3, 'alex']
def my_len(x,y,z):  #形参:形式参数
    count = 0
    for i in x:
        count += 1
    return count
ret = my_len(l2,s,'alex')  # 按位置传参
print(ret)
len(s)

结果:

   2 关键字参数  关键字位置可以互换

def mymax(x,y):
    #此时x = 20,y = 10  关键字 x y
    # print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(y = 10,x = 20) #x关键字  y关键字 各自对应一个参数位置可以互换
print(ma)

      3.位置、关键字形式混着用  

  • 混合参数正确用法

       问题一:位置参数必须在关键字参数的前面

       问题二:对于一个形参只能赋值一次

def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(10,y = 20)
print(ma)

混合传参

结果:

         4   默认参数

      为什么要有默认参数:将变化比较小的值设置成默认参数

def func(name,sex=''):
    with open('name_list','a',encoding='utf-8') as f1:
        f1.write('{}  {}
'.format(name,sex))
while True:
    name = input('请输入名字:')
    if '' in name:
        sex = input('请输入性别:')
        func(name,sex) #  混合
    else:
        func(name)

结果:

  5 动态参数 形参: 第3种 动态参数 *args 动态参数,不定长参数*args元组,他包含了你所有的位置参数.**kwargs包含所有关键字参数.

        要在位置参数后面,否则*args会把所有所有收走

def func(a,b,c,*args):
    print(a)
    print(b)
    print(c)
    print(args,type(args))
func(1,2,'alex',3,4,)

结果:

     **kwargs包含所有关键字参数.  放在位置参数,*args,默认参数后.

def func(a,b,c,*args,sex = '',**kwargs):
    print(a)
    print(b)
    print(c)
    print(sex)
    print(args,type(args))
    print(kwargs)
func(1,2,'alex','wusir','ritian ',sex = '',name = 'taibai',age = 21)

结果:

  6 万能参数  后面有多少个数据都能接收

def func2(*args,**kwargs):
    #万能参数
    print(args)
    print(kwargs)
func2(1,2,3,5,name='alex',age=56)

结果;

  7 魔法运算 将列表或字典内元素一个一个拿出来

# 魔法运算:
def func(*args):
    print(args)
li = [1,2,3]
l2 = [4,5,6]
func(li)       #输出结果:([1, 2, 3],)
func(*li)      #输出结果:(1, 2, 3)
func(*li,l2)   #输出结果:(1, 2, 3, [4, 5, 6])
func(*li,*l2)  #输出结果:(1, 2, 3, 4, 5, 6)



#*魔法运算:打散
def func2(*args,**kwargs):
    print(args)
    #(1,2,3)
l1 = [1,2,3,]
l2 = [1,2,3,2,3,100,2]
func2(*l2,*l1)
def func3(*args,**kwargs): print(args) print(kwargs) dic = {'name':'alex','age':12} dic2 = {'name':'jin','age':22} func3(**{'name1':'alex','age1':12},**{'name2':'jin','age2':22},name3 = 'wusir')

结果;

名称空间:
全局名称空间,
局部名称空间,
input,print sum le
 内置名称空间

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)


取值顺序:


  在局部调用:局部命名空间->全局命名空间->内置命名空间


  在全局调用:全局命名空间->内置命名空间


       在找寻变量时,从小范围,一层一层到大范围去找寻。


作用域


作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。


全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效


局部作用域:局部名称空间,只能在局部范围内生效

name = 'wusir'
def func():
    name = 'alex' #  取值范围 局部有先从局部找
    print(name)
func()

def len(x):
    return x               #取值范围 局部有 运行局部的  
print(len([1,2,3]))

结果:

作用域的角度:
全局作用域 包括 全局名称空间,内置名称空间
局部作用域 包括 局部名称空间,
name = 'wusir'
def func():
    name = 'alex'
    print(name)
    print(globals())    #全局
    print(locals())     #局部
func()
结果:

   8  函数嵌套  一个函数执行完以后才会执行后面的代码

print(111)
def fun2():
    print(222)
    def fun3():
        print(666)
    print(444)
    fun3()
    print(888)
print(333)
fun2()
print(555)

结果;

       

 9  global声明一个全局变量,如果在函数内改变,全局下也改变.(不可变类型时使用,可变类型不需要)

#global 1,声明一个全局变量
        #引用全局变量,并改变
def func():
    global a
    a = 2
    print(a)
func()
print(a)

结果:

如果可变类型就不需要global 因为本身就能改变

#可变的数据类型
l1 = [1,2,3]
def func():
    l1.append(444)
func()
print(l1)

结果:

 nonlocal与global相似,但是它只是作用于嵌套作用域,而且只是作用在函数里面

1,不能修改全局变量。

2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。被引用的外层不会被改变.

def func():
    name = 'wusir'
    def inner():
        nonlocal name
        name = 'taibai'
        print(name)
    print(name)
    inner()
    print(name)
func()

结果:

 父级函数下被引用,对本身和下一级函数有用,

def add_b():
    b = 42
    def do_global():
        b = 10
        print(b)
        def dd_nonlocal():
            nonlocal b
            b = b + 20
            print(b)
        dd_nonlocal()
        print(b)
    do_global()
    print(b)
add_b()

结果:

 

---恢复内容结束---

Python 函数

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

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

 1 定义一个函数

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

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

 2  return关键字的作用

  return 是一个关键字,在pycharm里,你会看到它变成蓝色了。你必须一字不差的把这个单词给背下来。

  这个词翻译过来就是“返回”,所以我们管写在return后面的值叫“返回值”

要研究返回值,我们还要知道返回值有几种情况:分别是没有返回值、返回一个值、返回多个值

没有返回值

  不写return的情况下,会默认返回一个None:我们写的第一个函数,就没有写return,这就是没有返回值的一种情况. 刚刚我们已经写过一个返回一个值的情况,只需在return后面写上要返回的内容即可。也可以返回任意多个、任意数据类型的值,返回的多个值会被组织成元组被返回,也可以用多个值来接收

只写return,后面不写其他内容,也会返回None,有的同学会奇怪,既然没有要返回的值,完全可以不写return,为什么还要写个return呢?这里我们要说一下return的其他用法,就是一旦遇到return,结束整个函数

def ret_demo():
    print(111)
    return
    print(222)

ret = ret_demo()
print(ret)

只写return

结果:

多个值接收

def ret_demo2():
    return 1,['a','b'],3,4

#返回多个值,用一个变量接收
ret2 = ret_demo2()
print(ret2)

#返回多个值,用多个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)

#用多个值接收返回值:返回几个值,就用几个变量接收
a,b,c,d = ret_demo2()
print(a,b,c,d)

多个返回值的接收

多个值接收

结果:

  3 参数

可更改(mutable)与不可更改(immutable)对象

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

  • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。

  • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

python 函数的参数传递:

  • 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

  • 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

参数

以下是调用函数时可使用的正式参数类型:

  • 位置参数
  • 关键字参数
  • 默认参数
  • 混合参数

位置参数

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

调用printme()函数,你必须传入一个参数,不然会出现语法错误:

s = 'fdsafsda'
l2 = [1, 2, 3, 4, 5, 6, 5, 4, 3, 3, 'alex']
def my_len(x,y,z):  #形参:形式参数
    count = 0
    for i in x:
        count += 1
    return count
ret = my_len(l2,s,'alex')  # 按位置传参
print(ret)
len(s)

结果:

   2 关键字参数  关键字位置可以互换

def mymax(x,y):
    #此时x = 20,y = 10  关键字 x y
    # print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(y = 10,x = 20) #x关键字  y关键字 各自对应一个参数位置可以互换
print(ma)

      3.位置、关键字形式混着用  

  • 混合参数正确用法

       问题一:位置参数必须在关键字参数的前面

       问题二:对于一个形参只能赋值一次

def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(10,y = 20)
print(ma)

混合传参

结果:

         4   默认参数

      为什么要有默认参数:将变化比较小的值设置成默认参数

def func(name,sex=''):
    with open('name_list','a',encoding='utf-8') as f1:
        f1.write('{}  {}
'.format(name,sex))
while True:
    name = input('请输入名字:')
    if '' in name:
        sex = input('请输入性别:')
        func(name,sex) #  混合
    else:
        func(name)

结果:

  5 动态参数 形参: 第3种 动态参数 *args 动态参数,不定长参数*args元组,他包含了你所有的位置参数.**kwargs包含所有关键字参数.

        要在位置参数后面,否则*args会把所有所有收走

def func(a,b,c,*args):
    print(a)
    print(b)
    print(c)
    print(args,type(args))
func(1,2,'alex',3,4,)

结果:

     **kwargs包含所有关键字参数.  放在位置参数,*args,默认参数后.

def func(a,b,c,*args,sex = '',**kwargs):
    print(a)
    print(b)
    print(c)
    print(sex)
    print(args,type(args))
    print(kwargs)
func(1,2,'alex','wusir','ritian ',sex = '',name = 'taibai',age = 21)

结果:

  6 万能参数  后面有多少个数据都能接收

def func2(*args,**kwargs):
    #万能参数
    print(args)
    print(kwargs)
func2(1,2,3,5,name='alex',age=56)

结果;

  7 魔法运算 将列表或字典内元素一个一个拿出来

#*魔法运算:打散
def func2(*args,**kwargs):
    print(args)
    #(1,2,3)
l1 = [1,2,3,]
l2 = [1,2,3,2,3,100,2]
func2(*l2,*l1)

def func3(*args,**kwargs):
    print(args)
    print(kwargs)
dic = {'name':'alex','age':12}
dic2 = {'name':'jin','age':22}
func3(**{'name1':'alex','age1':12},**{'name2':'jin','age2':22},name3 = 'wusir')

结果;

名称空间:
全局名称空间,
局部名称空间,
input,print sum le
 内置名称空间

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)


取值顺序:


  在局部调用:局部命名空间->全局命名空间->内置命名空间


  在全局调用:全局命名空间->内置命名空间


       在找寻变量时,从小范围,一层一层到大范围去找寻。


作用域


作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。


全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效


局部作用域:局部名称空间,只能在局部范围内生效

name = 'wusir'
def func():
    name = 'alex' #  取值范围 局部有先从局部找
    print(name)
func()

def len(x):
    return x               #取值范围 局部有 运行局部的  
print(len([1,2,3]))

结果:

作用域的角度:
全局作用域 包括 全局名称空间,内置名称空间
局部作用域 包括 局部名称空间,
name = 'wusir'
def func():
    name = 'alex'
    print(name)
    print(globals())    #全局
    print(locals())     #局部
func()
结果:

   8  函数嵌套  一个函数执行完以后才会执行后面的代码

print(111)
def fun2():
    print(222)
    def fun3():
        print(666)
    print(444)
    fun3()
    print(888)
print(333)
fun2()
print(555)

结果;

       

 9  global声明一个全局变量,如果在函数内改变,全局下也改变.(不可变类型时使用,可变类型不需要)

#global 1,声明一个全局变量
        #引用全局变量,并改变
def func():
    global a
    a = 2
    print(a)
func()
print(a)

结果:

如果可变类型就不需要global 因为本身就能改变

#可变的数据类型
l1 = [1,2,3]
def func():
    l1.append(444)
func()
print(l1)

结果:

 nonlocal与global相似,但是它只是作用于嵌套作用域,而且只是作用在函数里面

1,不能修改全局变量。

2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。被引用的外层不会被改变.

def func():
    name = 'wusir'
    def inner():
        nonlocal name
        name = 'taibai'
        print(name)
    print(name)
    inner()
    print(name)
func()

结果:

 父级函数下被引用,对本身和下一级函数有用,

def add_b():
    b = 42
    def do_global():
        b = 10
        print(b)
        def dd_nonlocal():
            nonlocal b
            b = b + 20
            print(b)
        dd_nonlocal()
        print(b)
    do_global()
    print(b)
add_b()

结果:

 

原文地址:https://www.cnblogs.com/wzbk/p/8393997.html