python的函数

定义python的函数

def myPyFunction():
    print('这是一个python的一个函数方法')

关键字参数

当参数过多的时候,为了防止因为入参顺序位置搞错了,指定形参的变量名,防止函数调用有误或者报错的问题。

def saySomething(name,words):
    print(name +'->'+words)

saySomething(words="说句话",name="songcuiting")
#songcuiting->说句话

使用默认参数的话可以不带参数进行默认参数的调用

def saySomething(name='song',words='写了一天的bug累了吗'):
    print(name+"->"+words)


saySomething();
#song->写了一天的bug累了吗 saySomething(
"gai","老子吃火锅,你吃火锅底料")
#gai->老子吃火锅,你吃火锅底料

收集参数(可变参数)

写法:只需要在参数前追加*符号就可以。

当不确定入参个数的情况下可以用到,收集参数被当做一个元组。如果在收集参数后面还需要指定其他参数,在调用函数的实惠就用该关键字参数来指定,否则python会将所有参数都列入收集参数的范围中。

def test(*params):
    print("有%d个参数" % len(params))

#有5个参数

#其中%d是数字占位符

 

def test(*params,extra):
  print("收集参数是:",params)
  print("关键字参数是:",extra)


#调用
test(1,2,3,4,5,6,7,8)
#这种调用会报错,没有使用关键字参数的都会被打包进收集参数中,打包成一个元组。 #TypeError: test() missing
1 required keyword-only argument: 'extra' test(1,2,3,4,5,6,7,extra=8) #收集参数是: (1, 2, 3, 4, 5, 6, 7) #关键字参数是: 8
#另外,在调用函数的时候,位置参数必须在关键字参数的前面,否则会报错


#建议写法是在定义方法的时候就将其他参数定位为默认参数,这样不容易出错
def test(*params,extra=8):
  print("收集参数是:",params)
  print("位置参数是:",extra)

 内嵌函数

允许函数内部创建另一个函数,这种函数叫做内嵌函数或者内部函数。

def fun1():
    print("fun1()正在被调用...")
    def fun2():
        print("fun2()正在被调用...")
    fun2()


调用:fun1()
结果:
fun1()正在被调用
fun2()正在被调用

不过需要注意的是只有在调用fun1的时候fun2才能被调用到。直接调用fun2是找不到这个函数的,会报错的。

 闭包

如果在一个内部函数中(funY就是一个内部函数)对外部作用域(但是不在全局作用域)的变量进行引用(x就是被引用的变量,x是外部作用域funX函数里面,但是不在全局作用域里),则这个内部函数(funY)就是一个闭包。 

#嵌套函数中,内部函数可以引用外部函数的局部变量
def funX(x):
    def funY(y):
        return x*y
    return funY

>>>i = funX(8)
>>>i(5)
40

#也可以直接这么写、
>>>funX(8)(5)
40
def funX():
    x=5
    def funY():
        x = x + 1
        return x
    return funY

>>>funX()()


##上诉写法会报错,这个错误提示与之前讲解全局变量的时候基本一样,Python认为在内部函数的x是局部变量的时候,外部函数的x就被屏蔽了起来,所以执行x = x + 1的时候,在等号右边根本就找不到局部变量x的值,因此报错。
##在Python 3以前并没有直接的解决方案,只能间接地通过容器类型来存放,因为容器类型不是放在栈里,所以不会被“屏蔽”掉。容器类型这个词大家是不是似曾相识?之前介绍的字符串、列表、元组,这些可以存放各种类型数据的“仓库”就是容器类型
##到了Python 3的世界里,有了不少的改进。如果希望在内部函数里可以修改外部函数里的局部变量的值,可以使用nonlocal关键字告诉Python这不是一个局部变量,使用方式与global一样(global后面会讲到)


def funX():
    x=5
    def funY():
     nonlocal x x = x + 1 return x return funY

>>>funX()()
 

 

 

lambda表达式

普通函数
def ds(x):
    return 2 * x +1


使用lambda函数:
>>> g = lambda x : 2 * x +1
>>> g(5)
11



多个参数使用lambda
普通函数
def add(x,y)
  return x +y

lambda表达式
>>>g = lambda x,y : x + y
>>>g(3,4)
7


 介绍两个内置函数 fiter()和map()

map这个内置函数也有两个入参,一个入参是函数,一个是可迭代的序列。

>>>list(map(lambda x : x *2 ,range(10)))
[0,2,4,6,8,10,12,14,16,18]

  变量作用域

# 如果在函数内部试图修改全局变量的值,那么Python会创建一个新的局部变量替代(名字与全局变量相同),但真正的全局变量是“不为所动”的,所以才有了上面的实现结果。
# 这点个java非常不一样,加上global关键字的效果其实和java就差不多了
count = 5;
def myFun():
  count = 10
  print(count)

>>>myFun()
10
>>>count
5


##global关键字##
count = 5;
def myFun():
  global count
  count = 10   print(count) >>>myFun() 10 >>>count 10

##像这种名字一样、作用域不同的变量引用,Python引入了LEGB原则进行规范。

 装饰器、“@语法糖”

def log(func):
    def wrapper(name):
        print("开始调用eat()函数...")
        func(name)
        print("结束调用eat()函数...")
    return wrapper

@log
def eat(name):
    print("%s开始吃了"%name)


>>>eat('fish')

##但这样的话就必须要时刻关注eat()函数的参数数量,如果修改了eat(),就必须一并修改装饰器log()。所以定义的时候使用收集参数,将多个参数打包到一个元组中,然后在调用的时候同样使用星号(*)进行解包,这样无论eat()有多少个参数,都不再是问题了。

 

posted @ 2019-07-18 15:47  宋songsong  阅读(270)  评论(0编辑  收藏  举报