[PY3]——Python的函数

Python函数总结图

  

1.调用

1.1 如何调用

   1.1.1  函数名(传参)

# 函数使用函数名来调用,函数名后紧跟一对小括号,小括号里传入函数定义时要求的参数
add(9,9)
#9+9=18

 

1.2 传参

   1.2.1  传参方法1:位置参数

   1.2.2  传参方法2:关键字参数

def add(x,y):
    ret=x+y
    print('{}+{}={}'.format(x,y,ret))
    return ret

# 传参方法1:位置参数  指参数按照定义的顺序传入
add(8,9)
#8+9=17

# 传参方法2:关键字参数  指参数按照定义时的变量名传入
add(x=9,y=8)
#9+8=17

# 规则1:位置参数和关键字参数可以混合使用
add(3,y=9)
#3+9=12

# 规则2:但混合使用时,位置参数必须在前面,否则SyntaxError
add(x=3,9) #SyntaxError: positional argument follows keyword argument # 注意1: add('3','9') #3+9=39 # 注意2:传入参数必须和函数定义时的参数相匹配,如果不匹配会抛出TypeError add(9,9,9) #TypeError: add() takes 2 positional arguments but 3 were given

 

1.3 参数解构

   1.3.1  位置参数解构:*可迭代对象

   1.3.2  关键字参数解构:*字典

iter=[3,9]
add(iter[0],iter[1])
#3+9=12

# 位置参数解构:*可迭代对象  可以把可迭代对象解构成位置参数
add(*iter)
#3+9=12
add(*range(2))
#0+1=1

# 关键字参数解构:*字典   可以把字典解构成关键字参数
# 关键字参数解构,key必须是str
dict={'x':3,'y':9}
add(**dict)
#3+9=12

 

2. 函数定义

2.1 如何定义

   def 函数名(参数列表):
                   执行语句
                   return 返回值

def add(x, y):     # 函数定义 def 表示定义一个函数;紧接着是函数名,函数名后面用一对小括号列出参数列表;参数列表后面使用一个冒号开始函数体
    print(x + y)   # 函数体是正常的Python语句,可以包含任意结构
    return  x + y  # return语句表示函数的返回值

 

2.2 函数的参数

   2.2.1  普通参数

   2.2.2  默认参数

   2.2.3  可变参数(*变量  **变量)

   2.2.4  keyword-only参数

   2.2.5  参数设置规则

# 可以为参数设置默认值,调用时如果不传递此参数,会使用默认值
def inc(x,y=9):
    print(x+y)

inc(1,10)
#11

inc(1)
#10
# 位置可变参数:*变量  构成元祖,以位置参数的形式传参
def sum(*lst):
    print(type(lst))
    ret=0
    for x in lst:
        ret+=x
    print(ret)

sum(1,2,3,4,5)
#<class 'tuple'>
#15
sum(1,2,3)
#<class 'tuple'>
#6

# 关键字可变参数:**变量  构成字典,以关键字参数的形式传参
def connect(**kwargs):
    print(type(kwargs))
    for k,v in kwargs.items():
        print('{}——>{}'.format(k,v))

connect(host='127.0.0.1',port=3306)
#<class 'dict'>
#host——>127.0.0.1
#port——>3306

# 所以如果要创建一个接受任意类型参数的函数,可以如何定义?
def wrap(*args,**kwargs)
# 规则1:普通参数和可变参数可以一起使用,但传参必须匹配
def fn(x,y,*args,**kwargs):
    print("x=",x)
    print("y=",y)
    print("args=",args)
    print("kwargs=",kwargs)

fn(1,2)
#x= 1
#y= 2
#args= ()
#kwargs= {}

fn(1,2,0,2,6,a=3,b=9)
#x= 1
#y= 2
#args= (0, 2, 6)
#kwargs= {'b': 9, 'a': 3}

fn(2,y=3)
#x= 2
#y= 3
#args= ()
#kwargs= {}

fn(2,3,6,9,x=1)
#TypeError: fn() got multiple values for argument 'x'


# 规则2:位置可变参数如果放普通参数之前,普通参数会变成keyword-only参数
def fn(*args,x):
     pass
fn(2,3,0)
#TypeError: fn() missing 1 required keyword-only argument: 'x'


# 规则3:而关键字可变参数就不能在普通参数|默认参数之前
def fn(**kwargs,x):
     pass
#SyntaxError: invalid syntax

def fn(**kwargs,x=9):
    pass
#SyntaxError: invalid syntax

# 规则4:不建议可变参数和默认参数一起使用 def fn(*args,x=5): print(args) print(x) fn(1,2,3) #(1, 2, 3) #5 def fn(x=5,*args): print(x) print(args) fn(1,2,2) #1 #(2, 2) # 规则5:位置可变参数和关键字可变参数可以同时使用,但位置可变参数必须在前面 def fn(*args,**kwargs): print(args) print(kwargs) fn(1,2,3,a=3,b=9) #(1, 2, 3) #{'a': 3, 'b': 9} def fn(**kwargs,*args,): pass #SyntaxError: invalid syntax

 

3. 函数返回值

# 返回值除了返回值的作用外,还会结束函数,return后的语句将不会被执行
# 所以有结束函数作用的需求时,可以直接写“return”即可
def add(x,y):
    return x+y
    print("test")

print(add(3,9))
#12

# 一个函数可以有多个return,执行到哪个就由哪个返回并结束 def guess(x): if x>3: return '>3' print('end') return '<=3' print('end') print(guess(3)) #<=3 print(guess(9)) #>3
# return可以提前结束循环 # 没有return返回None def fn(x): for i in range(x): if i>=3: return i else: print('not bigger than 3') print(fn(10)) #3 #not bigger than 3 print(fn(2)) #None # return多个值时,可以用封装把返回值封装成一个元组、用解构来获取 def fn(): return 3,5 print(type(fn())) #<class 'tuple'> x,y=fn() print(x,y) #3 5

 

4.函数作用域

4.1 上下级作用域的变量的关系

# 函数内部是一个局部作用域,对上级作用域(全局作用域)的变量x ——>只读可见,不可操作
x=1
def inc():
     x+=1
inc()
#UnboundLocalError: local variable 'x' referenced before assignment

def inc():
     print(x)
inc()
#1
def fn():
     xx=1
     print(xx)
     def inner():
         print(xx)   #上级作用域的变量对下级作用域是可见的
     inner()
fn()
#1
#1

def fn():
     xx=1
     print(xx)
     def inner():
         xx=2      #在inner()作用域内定义的变量,那就只对该内部作用域及其下级作用域可见
         print(xx)
     inner()
     print(xx)
fn()
#1
#2
#1

4.2 global 标记全局变量

#global 全局变量
xx=2
def fn():
     global xx  #将上级作用域的xx变量标记为全局变量
     xx+=1      #则可对它操作了
fn()
print(xx)
#3

def fn():
   global aa=1    #注意global只能标记,并不能定义变量
   aa+=1
fn()
#SyntaxError: invalid syntax

#除非你清楚的知道global会带来什么,并且明确的知道,非global不行, 否则不要使用global

4.3 nonlocal 

def fn():
     xx=1
     print(xx)
     def inner():
          xx+=1   #对上级作用域定义的xx,原本是不可操作或定义的
          print(xx)
     inner()
fn()
#UnboundLocalError: local variable 'xx' referenced before assignment


def fn():
    xx=1
    print(xx)
    def inner():
        nonlocal xx  #nonlocal可以标记上一级作用域变量,使它可读可写
        xx+=1
        print(xx)
    inner()
fn()
#1
#2

 

5. 匿名函数(lambda)

5.1 lambda 可以怎样被定义和使用

lambda x:x+1
#<function __main__.<lambda>>

print((lambda x:x+1)(5))
#6

f=lambda x:x+1
print(f(5))
#6

# 匿名函数(lambda表达式) 只能写在一行上所以也有人叫它单行函数
f=lambda x: if x <0:
        0
    else:
        0
#SyntaxError: invalid syntax

5.2 lambda支持所有的参数列表及规则

# 匿名函数支持所有普通函数所支持的参数列表及规则
print((lambda :0)())
#0

print((lambda x,y:x+y)(3,5))
#8

print((lambda *args:args)(*range(3)))
#(0, 1, 2)

print((lambda *args,**kwargs:print(args,kwargs))(*range(3),**{str(x):x for x in range(3)}))
#(0, 1, 2) {'0': 0, '2': 2, '1': 1}

5.3 lamdba常和sorted( )等高阶函数一起使用

# 匿名函数通常用于高阶函数的参数,当此函数非常短小的时候,就适合使用匿名函数

 

6. 生成器函数(yield)

def gen():
    print('a')
    yield 1
    print('b')
    yield 2
    return 3

g=gen()

print(g)
#<generator object gen at 0x7f144845a308>

print(next(g))
#a
#1

print(next(g))
#b
#2

print(next(g))
#StopIteration: 3

# 带yield语句的函数称之为生成器函数, 生成器函数的返回值是生成器 
* 生成器函数执行的时候,不会执行函数体

* 当next生成器的时候, 当前代码执行到之后的第一个yield,会弹出值,并且暂停函数

* 当再次next生成器的时候,从上次暂停处开始往下执行

* 当没有多余的yield的时候,会抛出StopIteration异常,异常的value是函数的返回值

更多关于生成器参考:《[PY3]——函数——生成器(yield关键字)》

 

7. 函数执行流程

posted @ 2017-08-07 14:11  Jelly_lyj  阅读(175)  评论(0编辑  收藏  举报