Python函数基础

Python函数基础

【一】函数的表达式

def 函数名称([传递变量,[传递变量],[]]:
    ...
    [return 传递变量,[]]

#没有返回值
函数名称()
#有返回值
function1 = 函数名() 
  • []:表示内容可有可无

【二】函数的作用

  • 代码重用:减少重复编写代码

  • 提高代码可读性

  • 降低代码耦合度:避免不同代码之间的相互依赖

  • 提高代码可维护性:可对代码模块化处理,方便修改和扩展

  • 隐藏实现细节

【三】常见函数定义

【1】空函数

def register():
    pass
  • 作用:刚开始编写程序时,展示程序的体系结构

【2】无参无返回值

def hello():
	print("hello")

【3】有参数无返回值

# 一个参数
def hello(name):
    print(f"hello{name}")

# 多个参数
def add_num(a, b):
	print(f"{a}+{b}={a+b}")

【4】有参数有返回值

# 一个返回值
def hello(name):
    msg = f"hello{name}"
	return msg

# 多个返回值
def add_num(a, b):
	return a*2, b**2		# 多个返回值以元组形式返回

【四】函数的调用

【1】直接调用

def hello(name):
    msg = f"hello {name}"
    return msg

result = hello("tom")
print(result)				# hello tom

【2】间接调用(常用)

def register():
    print("register")


def login():
    print("login")


function_dict = {"1": register, "2": login}
choice = input("").strip()
function_run = function_dict.get(choice)
function_run()

【3】函数作为参数

def add_num(a, b):
    return a + b


def run(function, a,b):
    return function(a, b)

res = run(add_num, 1, 3)
print(res)

【五】函数的参数

【1】定义

  • 形参:在声明函数时,括号里的变量。用来接收外部传来的值
  • 实参:在调用函数时,括号内传入的值。可以是常量、变量、表达式等
def add_num(a, b):
    print(f"{a}+{b}={a + b}")


# 常量
add_num(1, 2)
# 变量
a, b = (1, 2)
add_num(1, 2)
# 表达式和常量
add_num(1, 2 if 2 > 0 else -2)

【2】参数的位置

def add_num(a, b, c):
    print(f"{a}+{b}+{c}={a + b + c}")

# 对应位置传参数
add_num(1, 2, 3)
# 关键字传参数
add_num(b=2, a=1, c=3)
  • 混合使用时,在关键字传参后面不能再通过位置传参数
def add_num(a, b, c):
    print(f"{a}+{b}+{c}={a + b + c}")


# 错误
add_num(1, b=2, 3)  		# 报错
add_num(a=1, 2, 3)			# 报错
# 正确
add_num(1, b=2, c=3)

【3】默认参数

  • 默认参数需要卸载最后
def register(name, age = 18, gender):					#报错
    print(f"name:{name}\tage:{age}\tgender:{gender}")

register("tom", 20)`
  • 默认参数传值不传值
def register(name, age = 18, gender = "female"):
    print(f"name:{name}\tage:{age}\tgender:{gender}")

register("tom", 20)
# name:tom	age:20	gender:female
# 不传递值就是默认值,传递值就会覆盖掉默认值
  • 默认参数为可变数据类型
def add_user(name, age, user_dict=None):
    if user_dict  == None:
        user_dict = dict()
    user_dict[name] = age
    print(user_dict)

add_user("tom", 12)			# 没有指定每次都是申请新空间
add_user('lucy', 45)
add_user('Kan', 23)
# {'tom': 12}           
# {'lucy': 45}
# {'Kan': 23}
  • 默认参数的值通常是设为不可变类型

【4】可变长参数

(1)*args, 可变长位置参数
  • 多的参数将以元组的形式存在args

  • *的用法补充(可以打开元组、列表、集合

def func(a, *args):
    print(a, args)
 
# 多的参数将以元组的形式存在args
func(1, 2, 3)
# 1 (2, 3)
def func(a, *args):
    print(a, args)

# *可以打开元组、列表、集合
func(1, (2, 3))
func(1, *(2, 3))
# 1 ((2, 3),)
# 1 (2, 3)


a = {1, 2, 3}
print(*a)
# 1 2 3
(2)**kwargs, 可变长关键字参数
  • 关键字传参的内容都将以字典的形式放在kwargs
  • **的用法补充, 打开字典
def info(name, **kwargs):
    user_dict = {name: kwargs}
    print(user_dict)

# 通过关键字传参的内容都将以字典的形式放在kwargs中
info("tom", age=13, gender="male")
# {'tom': {'age': 13, 'gender': 'male'}}
def info(name, **kwargs):
    user_dict = {name: kwargs}
    print(user_dict)

# 打开字典chu
info("tom", **{"age": 13, "gender": "male"})
# {'tom': {'age': 13, 'gender': 'male'}}
(3)*args和***kwargs的混合使用(*args必须在前面)
def regiser(name, psw, *args, **kwargs):
    return(f"{name}--{psw}--{args}--{kwargs}")

res = regiser("tom", "23", "sing","basketball",gender = "male" )
print(res)
# tom--23--('sing', 'basketball')--{'gender': 'male'}
(4)命名关键字参数
  • 已知**kwargs后, 可以传入任意的key=value
  • 为了限制key,所以有了命名关键字参数
  • 在形参中,以*作为分割
  • 后面的形参都是命名关键字参数
  • 且必须以关键字参数的形式赋值
# gender和age都是命名关键字参数
def register(name,psw, *, gender="male", age):
    print(f"{name}-{psw}-{gender}-{age}")

# 正确
register("tom", "123",   gender="male", age=18)
register("tom", "123", age=18)


# 报错 无论是gender还是age都必须以关键字的形式传递参数
register("tom", "123", "male", 15)

  • 如果形参中有了*args,默认后面的都是命名关键字参数
def register(name,psw, *args, gender="male", age):
    print(f"{name}-{psw}-{gender}-{age}")


register("tom", "123",'123', gender="0", age=18)
(5)参数定义顺序要求

位置参数—默认参数 —*args —命名关键字参数— **kwargs

【六】名称空间和作用域

【1】名称空间

(1)内建名称空间
  • 伴随python解释器的启动/关闭而产生/回收,所以这是第一个被加载的空间,用来放置内置名字,比如函数名
(2)全局名称空间
  • 伴随python文件的开始执行/执行完毕而产生/回收,是第二个被加载的名称空间
  • 内置名称空间+第一层函数外的所有变量、函数名、类等 = 全局名称空间
(3)局部名称空间(函数)
  • 伴随函数的调用/结束而临时产生/回收
  • 函数的形参、函数内定义的名字都会被存放于局部名称空间
(4)名称空间的基本素顺序
  • 加载顺序: 内置名称空间 > 全局名称空间 > 局部名称空间
  • 回收顺序: 内置名称空间 < 全局名称空间 < 局部名称空间
  • 查找顺序: 先当前空间 - - > 然后逐层往外找
(5)特殊例子
# 会报错, 原因函数中先使用后定义
# 注释掉 x=222 就不会报错
x = 1
def func():
    print(x)
    x = 2

func()	

【2】作用域

(1)定义
  • 全局作用域:位于全局名称空间内建名称空间中
    • 该范围内的名字全局存活(除非被删除)、全局有效(在任意位置都可以使用)
  • 局部作用域:位于局部名称空间中
    • 该范围内的名字临时存活局部有效
  • 提示:可以调用内置函数locals()globals()来分别查看局部作用域和全局作用域的名字,查看的结果都是字典格式。在全局作用域查看到的locals()的结果等于globals()
(2)变量查找的顺序
  • 先当前空间 - - > 然后逐层往外找
# 在局部作用域中查找时:
局部名称空间 > 全局名称空间 > 内置名称空间
    
# 在全局作用域中查找时:
全局名称空间 > 内置名称空间 
(3)嵌套函数定义域
# 嵌套
def func1():
    a = 1
    def func2():
        a = 2
        print(f"func2作用域:{a}")
    print(f"func1作用域:{a}")
    return func2
func = func1()()

# func1作用域:1
# func2作用域:2
# 非嵌套
def func1():
    print(a)


def func2():
    a = 2
    return func1()


a = 1
func2()
# 1
(4)两个关键字参数的使用
  • global:在函数中修改全局不可变量
def login():
    print("登陆成功")
    # global flag  			#如果掉将死循环
    flag = False


flag = True
while flag:
    login()
# 登陆成功
  • nonlocal:在嵌套函数中可以将名字声明为来自外部嵌套函数定义的作用域(非全局
def run():
    def login():
        print("登陆成功")
        nonlocal flag
        flag = False

    flag = True
    while flag:
        flag = True
        login()


run()
# 登陆成功

你可能感兴趣的:(python,开发语言)