7. 函数-自定义函数

一、函数定义

# 形参
def func(a, b):
    c = a + b
    return c
# 实参
func(1, 2)

二、实参分类

1. 位置参数

1. 位置参数,传递参数时,需要形参、实参对应

def func(position1, position2):
    if position1 > position2:
        return position1
    else:
        return position2

def func(postiont1, position2):
    # 三元运算符
    c = a if a > b else b
    return c

2. 关键字参数

def func(name, address, age):
    pass

func(name='jone', age=18, address='北京')

3. 混合参数

注意: 在使⽤混合参数的时候, 关键字参数必须在位置参数后⾯

三、形参分类

1. 位置参数

# 位置参数. 按照位置来赋值
def func(name, address, age):
    pass

2. 默认值参数

# 在调⽤的时候可以给出具体的值, 也可以不给值, 使⽤默认值
def func(name, age, sax='男'):
    pass

4. *args

# 动态接收位置参数

def func(*args):
    # 以元组形式返回
    return args

func(1, 2, 3)

5. **kwargs

# 动态接收关键字参数

def func(**kwargs):
    # 以字典形式返回
    return kwargs

func(a = 1, b = 2, c = 3)

6. 动态传参的另一种方式

def fun(*args):
	print(args)
    
lst = [1, 4, 7]
# 可以使⽤*把⼀个列表按顺序打散
fun(*lst) 

s = "⾂妾做不到"
# 字符串也可以打散, (可迭代对象)
fun(*s) 
def fun(**kwargs):
	print(kwargs)
    
dic = {'a':1, 'b':2}
fun(**dic)

7. 传参顺序

位置参数 > *args > 默认值参数 > **kwargs 

四、函数注释

def chi(food, drink):
"""
这⾥是函数的注释, 先写⼀下当前这个函数是⼲什么的, ⽐如我这个函数就是⼀个吃
:param :param food: 参数food是什么意思
:param :param drink: 参数drink是什么意思
:return :return: 返回的是什么东东
"""
	print(food, drink)
	return "very good"

五、命名空间

1. 命名空间分类

1. 全局命名空间--> 我们直接在py⽂件中, 函数外声明的变量都属于全局命名空间
2. 局部命名空间--> 在函数中声明的变量会放在局部命名空间
3. 内置命名空间--> 存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置命名空间

2. 加载顺序

1. 内置命名空间
2. 全局命名空间
3. 局部命名空间(函数被执⾏的时候)

3. 取值顺序

1. 局部命名空间
2. 全局命名空间
3. 内置命名空间

4. globalnonlocal

(1) global
a = 100
def func():
    # 加了个global表示不再局部创建这个变量了. ⽽是直接使⽤全局的a
	global a 
	a = 28
	print(a)
    
func()
print(a)

结果:28 28
(5) nonlocal
1. nonlocal 表⽰在局部作⽤域中, 调⽤⽗级命名空间中的变量

a = 10
def func1():
	a = 20
    def func2():
        nonlocal a
        a = 30
        print(a)
    func2()
    print(a)
func1()

结果:
加了nonlocal
30
30
不加nonlocal
30
20

六、总结return

1. 遇到return. 此函数结束, 函数后⾯的东⻄将不会再执⾏
2. return 返回值
	如果return什么都不写 或者 ⼲脆不写return .那么返回的就是None
	如果return后⾯写了⼀个值. 则调⽤者可以接收⼀个结果
	如果return后⾯写了多个结果, 则调⽤者可以接收⼀个tuple, 调⽤者可以直接解构成多个变量

七、例子

1. 写函数,此函数只接收一个参数且此参数必须是列表数据类型
# 此函数完成的功能是返回给调用者一个字典,此字典的键值对为此列表的索引及对应的元素。
# 例如传入的列表为:[11,22,33] 返回的字典为 {0:11,1:22,2:33}。
def func(lst):
    if type(lst) != list:
        print("扔出去一个异常")

    dic = {}
    for i in range(len(lst)):
        dic[i] = lst[i]
    return dic


2. 写一个函数完成三次登陆功能,再写一个函数完成注册功能. 用户信息写入到文件中
# 注册
def regist(username, password): # wusir
    # 1. 检查用户名是否重复
    f = open("user_info", mode="r+", encoding="utf-8")
    for line in f:
        if line == "": # 防止空行影响程序运行
            continue
        user_info_username = line.split("_")[0]
        if username == user_info_username: # 用户名重复了
            return False
    else:
        # 2. 写入到文件中
        f.write(username+"_"+password+"\n")

    f.flush()
    f.close()
    return True

name, psw = input("请输入你的用户名:"), input("请输入你的密码:")
print(regist(name, psw))

# 登录
def login(username, password):
    f = open("user_info", mode="r", encoding="UTF-8")
    for line in f:
        if line.strip() == username+"_"+password:
            f.close()
            return True
    else:
        f.close()
        return False

for i in range(2, -1, -1):
    ret = login(input("请输入用户名:"), input("请输入密码:"))
    if ret:
        print("恭喜你. 登录成功")
        break
    else:
        print("用户名或密码错误, 还有%s次机会" % i)
      
    
3. 写函数,传入函数中多个实参(均为可迭代对象如字符串,列表,元祖,集合等),
# 将每个实参的每个元素依次添加到函数的动态参数args里面.
# 例如 传入函数两个参数[1,2,3] (22,33)最终args为(1,2,3,22,33)
def func(*args): # str, list, tuple, set
    print(args)
    lst = []
    for el in args:
        for e in el:
            lst.append(e)
    tu = tuple(lst)
    print(tu)

func(*"哈哈", *[1,3,5], *(456,789))
posted @ 2019-09-07 16:07  qi.hu  阅读(360)  评论(0编辑  收藏  举报