函数初识



一、函数的初识

函数是以功能为导向,函数内部尽量不要有print
def func():   #def 关键字,定义函数,空格 函数名(变量)
    # 函数体
    return 1,2,[123,2]

ret1,ret2,ret3 = func() #函数名 + ()就要执行此函数

print(ret1,ret2,ret3)
函数初识

二、return 功能

1.函数里面遇到return,此函数结束,下面就不再走了,终止函数
2.return 返回值: 不写return None
return None
return 单个

return 多个 将多个值包在元组中,返回给调用者,然后打印出打印者的值
例子1
def func():
    count = 2
    l1 = []
    l1.append(count)
    return l1,2,count
ret = func()
# print(ret)     元组类型

ret1,ret2,ret3 = func()
print(ret1,ret2,ret3)
View Code

三、函数的传参

1.函数的参数分为实体参数和形式参数
def my_len(x):     #形参:形式参数
    count = 0
    for i in l1:
        count += 1
    return count
l1 =[1,2,3,4,5,6]
ret = my_len(l1)    #实参:实体参数
print(ret)
View Code

2.实参:实体参数
从实参的角度:
(1)按位置传参,必须一一对应。
例子1
def func(x):
    if len(li) > 2:
        return True
    else:
        return False
li = [1,2,3,4]
print(func(li))

例子2
def func(x,y):
    # if x > y:
    #     return x
    # else:
    #     return y
    z = x if x > y else y      #三元运算法
    return z
i = 5
j = 6
print(func(i,j))
View Code
(2)按关键字传参
def func(x,y):

    z = x if x > y else y      #三元运算法
    return z

func(y = 2,x = 3)
View Code
(3)混合传参,位置参数在前面,关键字传参在后
def func(x,y,a,b):
    print(x,y)
    print(a,b)
    return x,y,a,b
ret = func(1,2,a = 3,b = 4)
print(ret)
View Code

2.形参传参:

(1)位置传参
(2)默认参数
例题:
def func(name,sex=""):
    with open("name_list","a",encoding = "utf-8") as f1:
        f1.write("{},{}".format(name,sex))
while 1:
    name = input("请输入名字=")
    if "xue" in name:
        sex = input("请输入性别")
        func(name,sex)
    else:
        func(name)

name = input("请输入名字")

sex =  input("请输入性别")

print(func(name))
View Code

四、函数的动态传参


1、 *args 动态参数,不定长参数

他包含了你所有的位置参数,打印出来的元素类型是是元组类型

args 需要放在位置参数前,否则会报错
例子1
args 需要放在位置参数前,否则会报错
def func(a,b,c,*args):
    print(a,b,c,*args)
func(1,2,3,4,5,6)

例子2
def func(*args):
    print(args,type(args))
func(1,2,3,4,"alex",5)

例子3
def func(*args):
    sum = 0
    for i in args:
        sum = sum + i
    return sum
print(func(1,2,3,6,78))

例子4
def func(*args):
    print(args,type(args))
func(1,2,"alex",3,4,5,6,7,8)   #(1, 2, 'alex', 3, 4, 5, 6, 7, 8) <class 'tuple'>
View Code

*args不给他传参,也不会报错,是个空元组
def func(a,b,c,*args):
    print(a)                 #1
    print(b)                 #2
    print(c)                 #alex
    print(args,type(args))   #()
func(1,2,"alex")
View Code

位置参数,*args,默认参数
def func(a, b, c,*args, sex= "nan"):
    print(a)       #1
    print(b)       #2
    print(c)       #3
    print(sex)     #
    print(args)    #(4, 5, 6, 5, 7)
    print(a,b,c,sex,args)
func(1,2,3,4,5,6,5,7,sex = "")
View Code

2、**kwargs()默认参数

例子1:打印出来的是字典数据类型,实参接受不定长的关键字参数
def func(**kwargs):
    print(kwargs)
func(a = 1 , b = 2, c = 3) #{'a': 1, 'b': 2, 'c': 3}
View Code

例子2:位置参数,*args,默认参数,**kwargs
def func(a,b,c,*args,sex="nan",**kwargs):
    print(a)
    print(b)
    print(c)
    print(args,type(args))       #(4, 5, 6, 5, 6, 4)    <class 'tuple'>
    print(sex)                    #nv
    print(kwargs,type(kwargs))     #{'name': 'taibai', 'name2': 'taibai2'}       #字典类型
func(1,2,3,4,5,6,5,6,4,sex = "nv",name = "taibai",name2 = "taibai2")
View Code
例子3:万能参数
def func(*args,**kwargs):
    print(args)
    print(kwargs)
func(1,2,3,4,5,name = "alex",age =15 )
View Code

3、魔法运算:打散

*args传入一个可迭代的对象就可以打散
例子1:
def func2(*args,**kwargs):
    print(args)
    print(kwargs)
l1 = [1,2,3]
l2 = [1,2,3,4,5,6,7]
func2(*l1,*l2)

例子2:*args
def func(*args,**kwargs):
    print(args,type(args))
    print(kwargs,type(kwargs))
dic1 = {"name":"alex","name1":"xue"}
dic2 = {"a":1,"b":2,"c":3}
func(*dic1,*dic2)  #('name', 'name1', 'a', 'b', 'c') <class 'tuple'>
View Code
**kwargs传入对象被打散
def func(*args,**kwargs):
    print(args,type(args))
    print(kwargs,type(kwargs))
dic1 = {"name":"alex","name1":"xue"}
dic2 = {"a":1,"b":2,"c":3}
func(**dic1,**dic2, name3 = "xue")
结果
() <class 'tuple'>
{'name': 'alex', 'name1': 'xue', 'a': 1, 'b': 2, 'c': 3, 'name3': 'xue'} <class 'dict'>
View Code

五、python的内部原理

 python代码运行的时候
 从python解释器开始执行之后,就可以在内存中开辟了一个空间,
每当遇到一个变量的时候,就把变量名和值之间对应的关系记录起来。


但是当遇到函数定义的时候,解释器只是象征性的将函数名读在内存,表示知道这个函存在了。
至于函数内部的变量和逻辑,解释器根本不关心。

等执行函数调用的时候,python解释器会再开辟一块内存储存这个函数里面的内容,
这个时候,才关注函数里面有哪些变量,而函数中的变量会储存再新开辟出来的内存中,
函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存的所有内容也会被清空。


“存放名字和值的关系“”  的空间 起了一个名字  命名空间
代码在运行开始,创建的存储“变量名和值的关系”的空间叫做  全局命名空间
在函数的运行中开辟的临时的空间叫做  局部命名空间

六、命名空间

命名空间:名称空间,全局名称空间,局部名称空间,内置名称空间
内置命名空间:input print sum len
加载顺序:内置名称空间---》全局名称空间 ---》局部名称空间(执行函数时)
取值顺序:局部空间找---》全局名称空间---》内置名称空间找
例子1:
name = "wusir"
def func():
    name = "alex"
    print(name)   #alex
func()

例子2:
name = 1
def func():
    n = 2
    print(666)   #NameError: name 'n' is not defined
print(n)

例子3:return后面是什么就返回什么
def len(x):
    return x
print(len([1,2,3]))    #[1, 2, 3]
View Code

七、作用域

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域
全局作用域:全局名称空间,内置名称空间。在整个文件的任意位置都能被引用、全局有效
局部作用域:局部名称空间,只能在局部范围内生效
name = "wusir"
print(globals())
def func():
    name = "alex"
    # print(globals())
    print(locals())     #{'name': 'alex'}
func()
View Code
 
def func1():
    print(222)
    def func2():
        print(111)
func1()    #222
func2()    #name 'func2' is not defined


例子2:
def func1():
    print(111)
def func2():
    print(222)
    def func3():
        print(444)
func2()   #222

例子3:
print(111)
def func2():
    print(222)
    def func3():
        print(666)
    print(444)
    func3()
    print(888)
print(333)
func2()
print(555)
View Code

八、global:

1.声明一个全局变量
2.在局部作用域想要对全局作用域的全局变量进行修改时,需要global(限于字符串、数字)

在局部作用域,对全局变量进行修改
def func():
    global a
    a = 3
func()
print(a)    # 3

例子2
count = 1
def search():
    global count
    count = 2
search()
print(count)   #2
View Code
对可变数据类型(list,dict,set)可以直接引用不用通过global
l1 = [1,2,3]
def func():
    l1.append(444)
func()
print(l1)     #[1, 2, 3, 444]
View Code

九、nonlocal:

1.不能修改全局变量
2.在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的那层,
从那层及以下此变量全部发生改变。
例子1
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()

例子2:

a = 1
def func():
    nonlocal a
    a = 2
    print(a)
func()   #SyntaxError: no binding for nonlocal 'a' found


例子2:
def func():
    name = "wusir"
    def inner():
        nonlocal name
        name = "taibai"
        print(name)
    inner()
    print(name)
func()
View Code

十、补充知识:

陷阱参数
def func(name,l = []):
    l.append(name)
    return l
print(func("alex"))  #['alex']
print(func("wusir")) #多次调用函数,保存了上次的值 #['alex', 'wusir']

 

 
原文地址:https://www.cnblogs.com/lara0520/p/8401242.html