python基础篇_003_函数

python中的函数

1.函数的目的

1.避免代码冗余
2.增强可读性

2.函数的定义与调用

# 定义函数 使用关键字def
"""
1.定义函数:
def 函数名():
    函数体
"""

def sayhello():
    print("hello")

"""
2.调用函数:
  函数名()
"""
sayhello()

 

3.函数返回值

# 函数的返回值
"""
1.什么都不写的情况下没有返回值
2.return  # 没有返回值 # 结束函数
3.return None
4.return 变量
"""

def say_hello1():
    print("hello")
print(say_hello1())


def say_hello2():
    print("hello")
    return
print(say_hello2()) 


def say_hello3():
    print("hello")
    return None
print(say_hello3())


def say_hello4():
    print("hello")
    return "hello"
print(say_hello4())

序列解压

# 序列的解压
a, b, c, d = (1, 2, 3, 4)
print(a, b, c, d)  # 1 2 3 4

a, _, _, d = (1, 2, 3, 4)

print(a, d)  # 1 4

a, *_ = (1, 2, 3, 4)
*_, d = (1, 2, 3, 4)
print(a, d)  # 1 4
# 字典、列表、集合同样适用
a, b = {'name': 'eva', 'age': 18}
print(a, b)  # age name

多个返回值

def demo():
    """多个返回值情况"""
    return 1, 2, 3, 'a'


"""多个返回值,用一个变量接收时,得到的是一个元祖"""
a = demo()
print(a)  # (1, 2, 3, 'a')

"""适用同等个数的变量接收,个数不相同,报错"""
a, b, c, d = demo()
print(a, b, c, d)

4.函数的参数

实参与形参

"""
1.定义函数使用的是形参
2.调用函数使用的是实参
"""

  

传参

实参角度

1.按照位置传参

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


demo(10, 20)

 

2.按照关键字传参

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


demo(y=10, x=20)

 

3.位置与关键字混用(位置参数必须在关键字参数的前面)

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


demo(10, y=20)  # 按照顺序

 

形参角度 : 位置参数必须传值

默认参数

def info(name, sex='male'):
    """将变化值较小的设置成默认参数"""
    print(name, sex)


# 调用函数时。默认参数可以不传值
info('a')
info('a', 'female')
def info(name, li=[]):
    """陷阱:默认参数是一个可变数据类型"""
    li.append(name)
    print(li)


info('a')  # ['a']
info('b')  # ['a', 'b']

区别其他语言:

package com.zzz

object Test {
  def demo(name: String, list: List[String] = Nil): List[String] = {
    return name :: list
  }

  def main(args: Array[String]): Unit = {
    val a = demo("a")
    val b = demo("b")
    print(a, b)   //(List(a),List(b))
  }
}

 

动态参数

"""
动态参数:
按位置传值多余的参数都由args统一接收,保存成一个元组的形式
"""


def to_sum(*args):
    sum = 0
    print(args)
    for i in args:
        sum += i
    return sum


a = to_sum(1, 2, 3)
print(a)
# (1, 2, 3)
# 6
b = to_sum(1, 2, 3, 4)
print(b)


# (1, 2, 3, 4)
# 10


# 接收k-v类型的参数

def info(**kwargs):
    print(kwargs)
    print(kwargs['name'], kwargs['sex'])


info(name='a', sex='b')
# {'name': 'a', 'sex': 'b'}
# a b

5.命名空间及作用域

"""
1.python解释器开始执行之后,就在内存中开辟了一个空间
2.每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来
3.当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心
4.等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,
  这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。
  函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

创建的存储“变量名与值的关系”的空间叫做全局命名空间,在函数的运行中开辟的临时的空间叫做局部命名空间
"""
# globals和locals方法
print(globals())
print(locals())  # 这中情况下,两种是一样的


def func():
    a = 12
    b = 20
    print(locals())  # {'b': 20, 'a': 12}
    print(globals())


func()
#global 关键字
a = 10
def func():
    global a
    a = 20

print(a) #10
func()
print(a) #20 

 

6.函数嵌套

def f1():
    print("in f1")
    def f2():
        print("in f2")

    f2()
f1()

 

"""
nonlocal关键字
# 1.外部必须有这个变量
# 2.在内部函数声明nonlocal变量之前不能再出现同名变量
# 3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效
"""

def f1():
    a = 1

    def f2():
        a = 2

    f2()
    print('a in f1 : ', a)


f1()  # a in f1 :  1


def f1():
    a = 1

    def f2():
        nonlocal a
        a = 2

    f2()
    print('a in f1 : ', a)


f1()  # a in f1 :  2

7.函数名的本质

"""函数名本质上就是函数的内存地址
1.可以被引用
2.可以被当作容器类型的元素
3.可以当作函数的参数和返回值
"""


def f1():
    return '1'


f = f1()
print(f)


def f2():
    return '2'


def f3():
    return ['a', 'b']


li = [f1(), f2(), f3()]
a = li[2]
print(a)

dict1 = {'f1': f1, 'f2': f2, 'f3': f3}
b = dict1['f1']  # <function f1 at 0x0000000001420378>
c = dict1['f1']()  # 1
print(b, c)

dict1 = {'f1': f1(), 'f2': f2(), 'f3': f3()}
d = dict1['f1']  # 1
print(d)
print('---------------')

def f5():
    return f1()
a = f5()
print(a)  # 1

8.闭包

内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数

def func():
    name = 'eva'
    def inner():
        print(name)
"""
想要拿到函数内部的变量和函数,返回变量跟函数
闭包函数用途
在函数外部调用函数内部的函数
"""


def func():
    name = 'zhangsan'

    def inner():
        print(name)

    return inner


f = func()
f()

判断是否是闭包函数方法__closure__

# 输出的__closure__有cell元素 :是闭包函数
def f1():
    name = 'zhangsan'

    def inner():
        print(name)

    print(inner.__closure__)  # (<cell at 0x0000000000E591C8: str object at 0x00000000008F37B0>,)
    return inner


f = f1()
f()

# 输出的__closure__为None :不是闭包函数
name = 'zhangsan'


def f2():
    def inner():
        print(name)

    print(inner.__closure__)  # 判断inner函数是不是闭包函数  None
    return inner


f2 = f2()
f2()
def f1():
    money = 1000
    def f2():
        name = 'zhangsan'
        def f3():
            print(name,money)
        return f3
    return f2

f = f1()
i = f()
i()

 

posted @ 2019-04-24 11:26  问题不大1  阅读(209)  评论(0编辑  收藏  举报