Python函数小结

在编程语言中一般包含顺序,条件,循环,等各种结构当我们经常会做一些功能的时候每次
都写一模一样的代码就会显得很繁琐,我们就想把这些个功能一样的代码封装到一个某块中,
方便下次使用,这种东西我们一般叫做函数或者方法一般的函数
函数一般有以下几个要素 函数名、返回值、参数、函数体
一个基本的Python函数格式是这样的
def 函数名(参数):
 	函数体
 	return 返回值

#python本身为大家封装了一些函数 可以直接调用,比如:
print(abs(100),abs(-100))#取一个数字的绝对值
print(max(11,55,55,22,45,788,9777))#取最大值出来
#类型转换函数
print(int(‘34’),str(24),float(‘13.13’),float(‘13’),bool(0),bool(1))
#1.当对数字使用bool函数时,0返回假(False),任何其他值都返回真。
#2.当对字符串使用bool函数时,对于没有值的字符串(也就是None或者空字符串)返回False,否则返回True。

比如写一个函数求一个数的绝对值:
def fuction_abs(x):
    #类型检查
    if not isinstance(x,(int,float)):
        raise TypeError('bad operand type')
    if x>0:
        return x
    elif x<0:
        return -x
    else:#pass可以作为占位符 当没有想好这一块代码怎么写的时候可以写一个pass进去
        pass
Python还可以在函数中返回多个值,这一点看着很神奇,其实很扯淡
def move(x,y,step,angle):
    nx = x+step*math.cos(angle)
    ny = y-step*math.sin(angle)
    return nx,ny
def move2(x,y,step,angle):
    nx = x+step*math.cos(angle)
    ny = y-step*math.sin(angle)
    return [nx,ny]
def move3(x,y,step,angle):
    nx = x+step*math.cos(angle)
    ny = y-step*math.sin(angle)
    return (nx,ny)
**********************函数调用*******************************************
在调用函数的地方先要引用这个函数
from fuction import move2, move, move3 (注:fuction类名 move函数名)
p = move(100,100,60,math.pi/6)
print(p)
x,y = move(100,100,60,math.pi/6)
print(x,y)
name = move2(100,100,60,math.pi/6)
print(name)
tgg = move3(100,100,60,math.pi/6)
print(tgg)
然后看打印结果:
(151.96152422706632, 70.0)
151.96152422706632 70.0
[151.96152422706632, 70.0]
(151.96152422706632, 70.0)
**********************函数调用*******************************************
然后我们就发现了一个很扯淡的事情 所谓函数多个返回值实际上市返回了一个tuple,也就是说
#函数可以有多个返回值 多个返回值的情况下实际上是个tuple 也就是一个不可变数组
#因为tuple不可变 所以仍然是一个返回值

接下来我们要说一个关键性的问题:函数类型
有以下几个概念:位置参数、默认参数、必选函数、可变参数、关键字参数、命名关键字参数
下边将为大家逐一道来:
位置参数:顾名思义,调用函数的时候必须按照位置依次赋值,位置参数包括默认参数和必选参数,
懵逼了?没事,接着往下看:
#默认参数
#默认参数可以简化函数的调用 在位置参数没有传的时候 避免报错 降低调用函数的难度
#一是必选参数在前,默认参数在后
#当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数
#默认参数必须指向不变对象!这一点很重要
也即是说当函数调用的时候,位置参数一定要有值,必选参数必须传值,默认参数因为有默认值可以不传,但是这两者在函数体里边一定是能拿到值的,貌似是这样的,反正我是这么理解的,并且,必选参数一定要在默认参数前边!!!

下边看两个例子
求x的n次方 x^n
函数1:
def power(x,n):
    s=1
    while(n>0):
        n-=1;
        s*=x
    return s
函数2:
def power(x,n=2):
    s=1
    while(n>0):
        n-=1;
        s*=x
    return s

上边的两个函数不同点就在于第一个里边的n是一个位置参数 同时是一个必选参数,在调用的时候必须传入x和n的值才能正常的调用函数
而第二个函数中的n则是一个位置函数 同时又是一个默认参数,在调用的时候只要传入正常的x的值就能正常的调用函数

以第二个为例
print(power(5,2),power(5,5),power(5))
打印结果为:
25 3125 25

可变参数:

比如我们想让函数接收一个list或者tuple类型的参数,我们可以这么做
def calc(numbers):
    sum = 0
    for n in numbers:
        sum+=(n*n)
    return sum
   调用:
print('传入list打印结果:',calc([1,3,4]))
print('传入tuple打印结果:',calc((1,3,4))) 
得到的结果完全一样

#定义可变参数和定义一个 list 或 tuple 参数相比,仅仅在参数前面加了一
#个*号。在函数内部,参数 numbers 接收到的是一个 tuple,因此,函数
#代码完全不变。但是,调用该函数时,可以传入任意个参数,包括 0 个参数
于是函数可以变成

def calc2(*numbers):
    sum = 0
    for n in numbers:
        sum+=(n*n)
    return sum
调用:
print('可变参数打印结果:',calc2(1,3,4))#多个参数用一个tuple接收
print('可变参数打印结果:',calc2(*(1,3,4)))#直接传入一个tuple但是在调用的时候要在前边加*

关键字参数
#关键字参数允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个 dict
#和可变参数类似,也可以先组装出一个 dict,然后,把该 dict 转换为关键字参数传进去 在传参的时候前边加**
#**extra 表示把 extra 这个 dict 的所有 key-value 用关键字参数传入到函数的 **kw 参数, kw 将获得一个 dict,注意 kw 获得的 dict 是 extra 的一份拷贝,对 kw 的改动不会影响到函数外的 extra

在定义关键字参数的时候要在前边加**
def enoll2(name,genger,**kw):
    print('name:',name,"genger:",genger,'kw:',kw)
调用:
enoll2('Toamae','F',city='BeiJing',job = 'chuiniu')
enoll2('Toamae','F',**{'city':'BeiJing','job':'chuiniu'})
dict_c = {'first':'第一个','second':'第二个','third':'第三个'}
enoll2('花生油','F',**dict_c)#先组装一个dict 然后传入 但是前边要加**
关键字参数打印结果:
name: Toamae genger: F kw: {'city': 'BeiJing', 'job': 'chuiniu'}
name: Toamae genger: F kw: {'city': 'BeiJing', 'job': 'chuiniu'}
name: 花生油 genger: F kw: {'first': '第一个', 'third': '第三个', 'second': '第二个'}

命名关键字参数:
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。
至于到底传入了哪些,就需要在函数内部通过 kw 检查,如果要限制关键字参数的名字,
就可以用命名关键字参数,例如,只接收 city 和 job 作为关键字参数
定义如下:

def person(name,age,*,city,job):
    print('name:',name,'age:',age,'city:',city,'job:',job)
#命名关键字参数可以有缺省值,从而简化调用
def person2(name,age,*,city='Beijing',job):
    print('name:', name, 'age:', age, 'city:', city, 'job:', job)
和关键字参数 **kw 不同,命名关键字参数需要一个特殊分隔符 * , * 后面
的参数被视为命名关键字参数
调用:
person('死啦死啦',36,city='BeiJing',job='吹牛逼')#命名关键字参数
person2('死啦死啦',36,job='吹牛逼')#命名关键字参数
命名关键字打印结果:
name: 死啦死啦 age: 36 city: BeiJing job: 吹牛逼
name: 死啦死啦 age: 36 city: Beijing job: 吹牛逼
#TODO 在 Python 中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,
#TODO 这 5 种参数都可以组合使用,除了可变参数无法和命名关键字参数混合
#TODO 必选参数在前,默认参数在后 (*可变参数 **关键字参数可以一块用,可变参数不能和命名关键字参数一块用)
****************************范例*******************************
def f1(a, b, c=0, *args, **kw):√正确
   print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):√正确
   print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
def f2(a, b, c=0, *, d, *kw):×错误
   print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
****************************范例******************************
定义:
def f1(a,b,c=0,*args,**kw):#必选参数 默认参数 可变参数 关键字参数
    print('a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw)

def f2(a, b, c=0,*,d=0,**kw):#必选参数 默认参数 ,命名关键字参数 关键字参数
    print('a=',a,'b=',b,'d=',d,'kw=',kw)
 ****************************组合调用******************************************
调用:
#只传入必选参数 结果可以拿到默认参数 一个空的tuple接收可变参数 一个空的dict接收关键字参数
f1('bbc','ccd')
#传入必选参数 传入默认参数 结果可以拿到传入的默认参数 一个空的tuple接收可变参数 一个空的dict接收关键字参数
f1('bbc','ccd','gfdg')
#传入必选参数 默认参数 可变参数 关键字参数 看打印结果 可变参数虽然用一个tuple来接收 但是传的时候还是要一个一个传
#以下两种打印结果一样
#**{'ff':'vv','bb':"nnn"} ff='vv',bb='nnn'两者传参方式一样
f1('dsgsdf','fsdf','fdsfs',12,323,23,**{'ff':'vv','bb':"nnn"})
f1('dsgsdf','fsdf','fdsfs',12,323,23,ff='vv',bb='nnn')
#如果可变参数真的想传入一个tuple 在传参的时候前边加*
f1('dsgsdf','fsdf','fdsfs',*(12,323,23),**{'ff':'vv','bb':"nnn"})
f1('dsgsdf','fsdf','fdsfs',*(12,323,23),ff='vv',bb='nnn')
f2('bbc','ccd')
#传入必选参数 传入默认参数 结果可以拿到传入的默认参数 一个空的tuple接收可变参数 一个空的dict接收关键字参数
f2('bbc','ccd','gfdg')
#命名关键字参数可以有缺省值
#以下两种打印结果一样
#**{'ff':'vv','bb':"nnn"} ff='vv',bb='nnn'两者传参方式一样
f2('dsgsdf','fsdf','fdsfs',d='我是关键字参数',**{'ff':'vv','bb':"nnn"})
f2('dsgsdf','fsdf','fdsfs',d='我是关键字参数',ff='vv',bb='nnn')
打印结果:
a= bbc b= ccd c= 0 args= () kw= {}
a= bbc b= ccd c= gfdg args= () kw= {}
a= dsgsdf b= fsdf c= fdsfs args= (12, 323, 23) kw= {'bb': 'nnn', 'ff': 'vv'}
a= dsgsdf b= fsdf c= fdsfs args= (12, 323, 23) kw= {'bb': 'nnn', 'ff': 'vv'}
a= dsgsdf b= fsdf c= fdsfs args= (12, 323, 23) kw= {'bb': 'nnn', 'ff': 'vv'}
a= dsgsdf b= fsdf c= fdsfs args= (12, 323, 23) kw= {'bb': 'nnn', 'ff': 'vv'}
a= bbc b= ccd d= 0 kw= {}
a= bbc b= ccd d= 0 kw= {}
a= dsgsdf b= fsdf d= 我是关键字参数 kw= {'bb': 'nnn', 'ff': 'vv'}
a= dsgsdf b= fsdf d= 我是关键字参数 kw= {'bb': 'nnn', 'ff': 'vv'}
****************************组合调用******************************************

#默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
#要注意定义可变参数和关键字参数的语法:
#1.* args 是可变参数,args 接收的是一个 tuple;
#**kw 是关键字参数,kw 接收的是一个 dict。
#以及调用函数时如何传入可变参数和关键字参数的语法:
#可变参数既可以直接传入: func(1, 2, 3) ,又可以先组装 list 或 tuple,
#再通过 args 传入: func( * (1, 2, 3)) ;
#关键字参数既可以直接传入: func(city=‘BeiJing’,job = ‘chuiniu’) ,
#也可以通过 **kw 传入: func(
{‘city’:‘BeiJing’,‘job’:‘chuiniu’}) ;
还有关于递归函数的,巴拉巴拉 改天再写。。。。
就这么多,谢谢浏览

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值