python基础之函数v1

Python基础之函数

1:函数

一:什么是函数

函数就是对某一个功能的代码,进行打包。类似于一修车师傅有工具箱一样,需要用什么工具直接拿来用就行。

二:为什么要有函数

当需要重复的用一些功能的时候,就可以直接调用,不用再复制粘贴

三:函数的分类

三.一:内置函数
print,id,map,filter...都是内置函数,你只需要怎么用就行。。。
三.二:自定义函数
就是你需要用什么功能,都是需要自己造

四:使用函数的优点

1,代码逻辑清晰,可读性好
2,不用写重复的代码
3,后面扩展容易,管理方便

2:函数的定义

一:如何定义函数

#语法
def 函数名(参数1,参数2,参数3,...):
    '''注释'''
    函数体
    return 返回的值

#函数名要能反映其意义
def login():
	name = input('请输入你的用户名:')
	pwd = input("请输入的密码:")
	if name == 'alex' and pwd = 'alexdsb':
		print('登录成功')
	else:
		print("登录失败!")

#上述代码定义函数

二:函数的使用(先定义,后调用)

# 函数与变量的定义也差多,变量名如果不定义,调用变量就睡报错,函数名其实可以理解为变量名,不定义调用就报错

def login():
	name = input('请输入你的用户名:')
	pwd = input("请输入的密码:")
	if name == 'alex' and pwd = 'alexdsb':
		print('登录成功')
	else:
		print("登录失败!")

login() # 这就是调用函数

测试一

def f1():
	print('from f1')
	f2()

f1()	

测试二

def f2():
	print('from f2')
	f1()

def f1():
	print('from f1')
	
f2()

测试三

def f1():
	print('from f1')
	f2()
i
def f2():
	print("from f2")

f1()

结果

测试一报错
测试二和测试三正常
结论:函数的使用,必须先要定义,后调用。
使用函数时,一定要明确区分定义阶段和调用阶段

三:函数定义解释器做了什么?

#只检测语法,不执行代码
也就说,语法错误在函数定义阶段就会检测出来,而代码的逻辑错误只有在执行时才会知道

四:函数定义的三种形式

一:无参
应用场景仅仅只是执行一些操作,比如与用户交互,打印
def foo():
	print('foo')
二:有参
需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值
def max_(arg1, arg2):
    '''
    参数必须是int类型
    '''
	if arg1 > arg2:
		print(arg1)
	else:
		print(arg2)
三:空函数
设计代码结构
def login():
	pass
	
def registry():
	pass
    
........        

3:调用函数

一:调用函数

函数的调用:函数名加括号
1 先找到名字
2 根据名字调用代码
def foo():
	print("foo")
	
foo() # 这就是调用函数	

二:函数返回值

一般没有定义返回值,函数默认的返回值为None

返回值要用关键字return
return 可以返回单个值,或者多个值(多个值是以元组的形式放回)
# 默认
def foo():
	print('foo')
	
# 一个值
def foo():
	print('foo')
	return 'foo'

# 多个值
def foo():
	print('foo')
	return 0, 1, 2, 'foo'


三:函数调用的三种形式

一:语句形式

foo()

二:表达式形式

res = 3*len('helloword')
print(res)

三:函数作为另外一个函数的参数

res = max(max(1,30),3)
print(res)

4:函数的参数

一:形参与实参

形参即变量名,实参即变量值,函数调用时,将值绑定到变量名上,函数调用结束,解除绑定
def max_(arg1, arg2): # arg1与arg2是形参
    '''
    参数必须是int类型
    '''
	if arg1 > arg2:
		print(arg1)
	else:
		print(arg2)

res = max_(100,101)  # 100和101是实参      

二:参数分类

一:位置参数
1:位置形参
1、位置形参:按照从左到右的顺序依次定义形参
特点:必须被传值,多一个不行少一个也不行
def foo(x, y, z):
	print(x, y, z)
foo(1,2,3)
foo(1) # 报错

2:位置实参
2、位置实参:按照从左到右的顺序依次定义实参
特点:按照位置与形参一一对应

def bar(x,y):
	print(x,y)
	
bar(3,1)
bar(1,3)	
二:关键字实参
关键字实参:按照key=value的形式为指定的形参传值
特点:指名道姓为某个形参传值,可以完全打乱顺序

def foo(x,y):
	print(x,y)
	
foo(x=1,y=2)
foo(y=2,x=1)
foo(2,1)
/////////////////////////////////
def bar(x,y):
	print(x,y)

bar(1,2,x=101) # 报错
warning:关键字实参与位置实参可以混用,但是不能对同一个形参重复赋值
////////////////////////////////
def func(x,y):
	print(x,y)

func(x=1,3) # 报错
func(1,y=3)
func(y=3,1) # 报错
Warning:关键字实参必须放到位置实参右边
三:默认参数
默认参数:具有默认值的形参,指的是在定义函数阶段就已经为参数赋值,这意味着在调用函数阶段可以不用为默认参数传值

def  func(x,y=1111):
	print(x,y)

func(100)
func(100,101)

def func(y=111,x):
	print(x,y)
定义的时候就保错了
warning:位置形参必需在默认参数左边
/////////////////////////////

def func(name, names=[]):
    # name = "张三"
    # names=[]
    names.append(name)  # names=["张三"]
    print(names)


func("egon")
func("张三")
func("李四")
默认形参的值是在函数定义阶段就被固定的,如果调用没有为默认形参传值,那么不会每次调用都重新赋值

函数的调用彼此之间应该做到没有关联,所以说默认形参的通常应该是不可变类型

def func(name, names=None):
    if names is None:
        names = []
    names.append(name)  # names=["张三"]
    print(names)

func("egon")
func("张三")
func("李四")
四:可变长参数
一:可变长参数
可变长指的是在调用函数时,传入的实参个数不固定,而实参是为形参赋值的
所以对应着也应该有新的形参格式来负责接收不固定长度的实参
二:*args形参
def func(a,b,*args):
	print(a,b,args)

func(1,2) # 1 2 ()
func(1,3,4) # 1 2 (4,)
func(3,4,5,6) # 3 4 (5,6)
func() # 报错
*形参名:*会负责把溢出的位置实参存成元组然后赋值给后面的形参名,形参名通过应该是args
三:**kwargs形参
def bar(x,y,z=11,**kwargs):
	print(x,y,z,kwargs)

bar(1,2,a=1,c=2,d=3) #1 2 11 {'a': 1, 'c': 2, 'd': 3}
**形参名:**会负责把溢出的关键字实参存成字典然后赋值给后面的形参名,形参名通过应该是kwargs

四:*args实参
def foo(x,y):
	print(x,y)

foo(*(2,3))
foo(*'he')
foo(*[1,2])
foo(*{'k1':1,'K3':3})
foo(*(1,2,3)) # 报错 这个是因为打散以后有三个值,但是函数的位置形参只有两个,所以报语法错误 
warning实参中带*,*后跟的那个值应该是一个可以被for循环遍历的值。*会后面的那个值打散成位置实参(应该是可迭代数据类型)
五:**kwargs实参
def bar(x,y):
	print(x,y)

bar(**{'k1':1,"k2":3})
bar(**{'name':"alen",'age':18})
bar(**{'name':'sb','gender':'female'})
实参中带**,**后跟的那个值应该是一个字典。**会后面的那个值打散成关键字实参


六:参数中混用*args,**kwargs
def foo(*args,**kwargs):
	print(args,kwargs)
	
foo(1,2,3,4,5,6,x=1,b=3,c=4,d=1)  # (1, 2, 3, 4, 5, 6) {'x': 1, 'b': 3, 'c': 4, 'd': 1}
foo(*[1,2,3,4,5],**{'x':1,'y':2}) # (1, 2, 3, 4, 5) {'x': 1, 'y': 2}
foo((1,2,3,4,5),{'k2':1,'k2':3})
/////////////////////////////

def inner(x,y):
	print(x,y)
	
def wrapper(*args,**kwargs):
	inner(args,kwargs)
	
wrapper(1,2) # (1,2) {}
wrapper(x=1,y=2) # () {'x':1,'y':2}
wrapper(1,y=2) # (1,) {'y':2}
七:扩展
#5、命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
可以保证,传入的参数中一定包含某些关键字
def foo(x,y,*args,a=1,b,**kwargs):
    print(x,y)
    print(args)
    print(a)
    print(b)
    print(kwargs)

foo(1,2,3,4,5,b=3,cc=4,dd=5)
结果:
    1
    2
    (3, 4, 5)
    1
    3
    {'cc': 4, 'dd': 5}

5:函数的进阶应用

引子

在python中函数是第一类对象,简称函数对象
函数对象指的就是可以把函数当做变量一样去使用
1:赋值
def bar():
	print('from bar')
print(bar)
f=bar
f()

2:可以当做参数传给另外一个函数
def func(aaa):
	print(aaaa)
	aaa()

def foo():
	print("from foo")

func(foo)

3:可以当做函数的返回值
def foo(aaa):
	return aaa

def bar():
	print('from bar')

res=foo(bar)
print(res)
res()
4:可以当做容器类型的元素
def foo():
	print("from foo")
l=[]
l.apend(foo)
l[0]()
# 示范
def login():
    print('登录功能')


def register():
    print('注册功能')


def transfer():
    print('转账功能')


def charge():
    print('充值')

def withdraw():
    print('提现')

func = {
    "1": ("登录",login),
    "2": ("注册",register),
    "3": ("转账",transfer),
    "4": ("充值",charge),
    "5": ("提现",withdraw)
}


while True:
    print("0 退出")
    for k,v in func.items():
        print(k,v[0])
    choice = input("请输入你的操作编号:").strip()
    if choice == "0":
        break
    if choice in func:
        func[choice][1]()
    else:
        print("输入的指令不存在")
原文地址:https://www.cnblogs.com/wait59/p/13149679.html