6 python--函数

一、函数的作用

#1、代码的组织结构不清晰,可读性差
#2、遇到重复的功能只能重复编写实现代码,代码冗余
#3、功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大

 

二、函数的定义

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

#函数名要能反映其意义

三元表达式
x = 10
y = 2
if x > y:
    print(x)
else:
    print(y)

res = x if x>y else y  # if条件成立返回x,else 返回y ,可自定义返回值
print(res)

定义有参函数:函数的功能的执行依赖于外部传入的参数,有参函数通常需要返回值

def my_max(x,y):
    res =x if x>y else y
    print(res)

空函数
def auth():
    """认证"""
    pass
auth()
View Code

 

#函数的参数

函数的参数按照定义和传递的情况时分为形式参数和实际参数。
  1、形式参数:在定义函数时,函数名后面括号中的变量名称叫做形式参数,或者成为形参。

  应用场景:仅仅执行一些操作,比如用户交互,打印等
  2、实际参数:在调用函数时,函数名后面括号中的变量名称叫做实际参数,或者成为实参。

  应用场景:需要提供外部传递的参数,才能执行相应的逻辑,比如统计长度等

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

foo(1,2)

import random
def check(n):
    code = ''
    for i in range(n):
        num = random.randint(1,9)
        s = chr(random.randint(65,90))
        add = random.choice([num,s])
        code +=str(add)

return code

print(check(3))

def foo(x,y,z): #位置参数,必须被传值的参数
    print(x,y,z)

foo(1,22,3)

关键字参数需要注意的问题:
1关键字参数必须在位置实参后面
2不能重复对一个形参传值
foo(1,z=3,y=5) 正确
foo(x=1,3,z=8) 错误

foo(1,x=1,y=3,z=5)

默认参数
1 默认参数必须跟在非默认参数后
def register(name,age,sex='male'): #形参:默认参数
    print(name,age,sex)

register('alex','aa')
2 默认参数在定义阶段已经赋值,而且只在定义阶段赋值一次
a.xml =10000000
def foo(x,y=a.xml):
    print(x,y)

a.xml=0
foo(1)

3 默认参数的值通常定义成不可变类型

可变长参数
def foo(x,y,*args): # *会把溢出的按位置定义的实参都接收,以元组的形式赋值给args
    print(x,y)
    print(args)

foo(1,2,3,4,5)

def add(*args):
    res = 0
    for i in args:
        res +=i
    return res
print(add(1,2,3,4))
print(add(1,2,3))

def foo(x,y,**kwargs): # **会把溢出的按关键字定义的实参接收,以字典的形式赋值给kwargs
    print(x,y)
    print(kwargs)

foo(1,2,a.xml=1,age=18)

def foo(name,age,**kwargs):
    print(name,age)
    if 'sex' in kwargs:
        print(kwargs['sex'])
    if 'height' in kwargs:
        print(kwargs['height'])

foo('egon',18,sex='male',height='185')
foo('egon',18,sex='male')

命名关键字参数(了解)

def foo(name,age,*,sex='male',height):
    print(name,age)
    print(sex)
    print(height)
#*后定义的参数为命名关键字参数,这类参数,必须被传值,而且必须以关键字实参的形式去传值
foo('egon',17,height='185')

def foo(*args):
    print(args)

foo(*['A','B','C','D'])  #*把列表值取出来,作为位置参数

def foo(**kwargs):
    print(kwargs)

foo(**{'y':2,'x':1})  #=foo(y=2,x=1)




def foo(x,y,z):
    print(x,y,z)
#
# foo(**{'z':3,'x':1,'y':2}) #foo(x=1,y=2,z=3

def wrapper(*args,**kwargs): #可以接收任意形式的参数
    print(args) #args=(1,2,3)
    print(kwargs) #kwargs={'a.xml':1,'b':2}
    # foo(**args,**kwargs) #foo(*(1,2,3),**{'a.xml':1,'b':2})

wrapper(1,2,3,a=1,b=2)
View Code
#1、位置参数:按照从左到右的顺序定义的参数
        位置形参:必选参数
        位置实参:按照位置给形参传值

#2、关键字参数:按照key=value的形式定义的实参
        无需按照位置为形参传值
        注意的问题:
                1. 关键字实参必须在位置实参右面
                2. 对同一个形参不能重复传值

#3、默认参数:形参在定义时就已经为其赋值
        可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)
        注意的问题:
                1. 只在定义时赋值一次
                2. 默认参数的定义应该在位置形参右面
                3. 默认参数通常应该定义成不可变类型


#4、可变长参数:
        可变长指的是实参值的个数不固定
        而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*args,**kwargs

        ===========*args===========
        def foo(x,y,*args):
            print(x,y)
            print(args)
        foo(1,2,3,4,5)

        def foo(x,y,*args):
            print(x,y)
            print(args)
        foo(1,2,*[3,4,5])


        def foo(x,y,z):
            print(x,y,z)
        foo(*[1,2,3])

        ===========**kwargs===========
        def foo(x,y,**kwargs):
            print(x,y)
            print(kwargs)
        foo(1,y=2,a=1,b=2,c=3)

        def foo(x,y,**kwargs):
            print(x,y)
            print(kwargs)
        foo(1,y=2,**{'a':1,'b':2,'c':3})


        def foo(x,y,z):
            print(x,y,z)
        foo(**{'z':1,'x':2,'y':3})

        ===========*args+**kwargs===========

        def foo(x,y):
            print(x,y)

        def wrapper(*args,**kwargs):
            print('====>')
            foo(*args,**kwargs)

#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,c=4,d=5)
        结果:
            2
            (3, 4, 5)
            3
            {'c': 4, 'd': 5}

此乃重点知识!!!
View Code

 

#函数的返回值

def foo():
    print('from foo')
    return None
res=foo()
print(res)

'''
以三种情况返回值都为None:
没有return
return 什么都不写
return None
'''

def foo():
    print('from foo')
    x=1
    return x
res=foo()
print(res)

# return 一个值  函数调用返回的结果就是这个值


def foo():
    print('from foo')
    x=1
    return 1,[2,3],(4,5),{}
# res=foo()
# print(res) #打印结果:(1,[2,3],(4,5),{})
# a,b,c,d=foo()
# print(d)



#return 值1,值2,值3,...   返回结果:(值1,值2,值3,...)

# t=(1,2,3)
# a,_,_=t
# print(a)

# t=(1,2,3,4,5,6,7,8,9)
# a,*_,c=t
# print(a)
# print(c)
View Code

#匿名函数,一些仅使用一次的函数可供使用

lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
func=lambda x,y,z=1:x+y+z 
func(1,2,3)

#内置函数

abs()  # 计算绝对值,abs(-10),接收number,返回一个number
  
max() # 求序列的的最大值(可迭代的),同时也可以比较一些数字
  
min() # 求序列的最小值(可迭代的),同时也可以比较一些数字
  
len() # 求序列的长度,(字典也可以,求index的个数)
  
divmod(x,y)    # 求x,y的商和余数,存放在元组中
  
pow(x,y,z) # 求x的y次方,如果有第三个参数,那么把前面的结果和第三个参数求余
  
round(number) # 用来四折五入,后面可以跟精度(先把number编程浮点数,然后看保留几位)把12.45转换成float,那么就不是12.45了,而可能是12.4999999了
  
callable() # 判断一个对象是否是可调用的,比如函数,类都是可以调用的,但是变量无法调用
  
type() # 查看对象的类型
  
isinstance(对象,类型) # 判断一个对象是否是给定类型。类型可以是多个,只要是其中1个即可(类型1,类型2)
  
cmp(x,y) # 比较两个对象的大小,x大于y返回1,x等于y返回-1,x小于y返回-1,字符串也可以比较,是按单个字符的大小开始比对。
  
str() # 可以把任何数据转换成字符串(字典,元组,也会直接输出)
  
hex(10) # 把10进制转换为8进制
  
eval() # 把字符串当做一个有效的表达式来求值
# eval('1+2') 返回3
# eval("[1,2,3]") 返回[1,2,3]
  
oct() # 把10进制转换为8进制
  
chr(i) # i的范围是0~255,求i对应的acsii码值
  
ord(i) # i的范围是ascii的值,求对应的值
  
filter(函数或空,序列) # 用来过滤,把序列的每一个元素,交给函数来处理。如果为None,则什么也不做,直接输出(序列),如果有函数,那么只有函数的返回值为True才打印序列中的元素
例子:
def even(n):
    if n % 2 == 0:
        return True
    filter(even,xrange(10))
    [0, 2, 4, 6, 8]
高级写法:
    filter(lambda x: x%2 ==0,xrange(10)
  
zip(seq1,seq2,seqN...) # 把seq1和seq2组合成1个大的列表,每个序列取1个组成元组,存放在整合后的列表中,如果序列的长度不同,那么就以最小的序列的长度为基准。
  
map(func,seq1,seq2) # 返回也是一个列表,func可以是一个函数也可以是个None,如果为None,那么返回的列表长度以当前最长列表为基准,依旧是依次去每个列表中去取,只不过没有的,用none补充
例子:
l1 = [1, 2, 3]
l2 = ['a', 'b', 'c', 'd']
l3 = ['I', 'II', 'III', 'IV', 'V', 'VI']
map(None,l1,l2,l3)
[(1, 'a', 'I'),
(2, 'b', 'II'),
(3, 'c', 'III'),
(None, 'd', 'IV'),
(None, None, 'V'),
(None, None, 'VI')]
# 如果函数位上是一个函数,那么如果只有1列表,那么就需要这个函数定义1个参数,然后每次把列表中的1个元素交给函数进行处理,并打印,或者保存在迭代器中去
# 如果需要处理两个序列,那么函数就必须定义2个参数,去接受这两个序列的元素。
# 高级应用:
map(lambda x,y:x+y,l1,l4)
  
reduce(func,seq) # 只能定义1个序列,然后传递给func进行处理。(lambda函数求累加)
View Code

 

posted on 2017-10-31 13:01  The_way-of_bigk  阅读(202)  评论(0编辑  收藏  举报