Cris 的Python笔记(六):函数基础

版权声明:转载请注明出处~ 摸摸博主狗头 https://blog.csdn.net/cris_zz/article/details/83338299

1. 函数基础语法知识

# 函数:函数也是一个对象,用来保存可执行的代码并且在需要时随时调用;而对象就是内存中用来存储数据的一片内存空间

# 创建函数:def 函数名([arg1,arg2...]):
#               代码块


def func():
    print('hello,cris')
    print('i am function of python')


# 调用函数
func()
print(type(func))   # <class 'function'>

# 函数的形参:定义形参相当于在函数内部定义了变量,但是并没有赋值
# 函数的实参:如果函数定义了实参,那么调用该函数时就需要传递对应的实参


def func(a, b):
    return a + b


result = func(1, 2)
print(result)   # 3

# 函数参数详解:1. 可以为函数的形参指定默认值,如果用户传递了参数,则默认值失效;如果用户没有传递实参,那么默认值生效
# 2.实参的传递方式:位置;关键字


def func(a, b, c=10):
    print(a, b, c)


# 位置传参
func(1, 2, 3)  # 1 2 3
# 关键字传参
func(c=11, a=12, b=0)  # 12 0 11
# 位置传参和关键字传参可以混合使用,但是位置参数必须写在关键字参数前面,否则无法区分
# func(b=12,23,11)    # 报错

# 函数调用时,无法对实参进行类型检查(Python 是一种动态语言);所以实参可以传递任意数据类型
func(func, 22)   # <function func at 0x000001836D1057B8> 22 10

# Python 中的值传递:实参如果指向的是可变数据类型的对象,那么函数中形参修改对象将会影响到所有指向这个对象的变量;
# 实参如果指向的是不可变数据类型,那么形参的修改将不会对实参产生任何影响(换句话说,Python和java 类似,参数传递都是值传递类型)


def func(a):
    a = 'cris'
    print(a)


b = 'james'
func(b)
print(b)

# 不定长函数:定义参数时,可以在一个形参前面加上*,这个形参就会获取到所有的实参,并且以元祖的形式展现,也称之为参数的装包
# 带* 号的参数只能写一个,并且可以和其他形参联合使用:例如(a,b,*c)
# 如果带* 号的形参写在中间,那么带* 号的形参后面的所有参数都必须以关键字的形式传递参数
# 如果在形参列表的开头写一个*,那么表示该函数的实参都必须以关键字的形式来传参:(*,a,b,c)


def sum(a, *b):
    print(a, b, type(b))


sum(1, 2, 3)    # 1 (2, 3) <class 'tuple'>


def sum(*nums):
    result = 0
    for i in nums:
        result += i
    print(result)


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

# *号形参只能接受位置参数


def func(*a):
    print(a)


func(1, 2, 3)  # (1, 2, 3)
# func(b=2, c=3)   # 报错

# 如果使用**号形参可以接受任意个关键字传参,默认会将这些参数统一保存到字典中,字典的key 就是参数的名字,value就是参数的值。**号形参只能写一个,并且必须写在最后一个


def func(**a):
    print(a)


func(b=1, c=2)   # {'b': 1, 'c': 2}

# 参数的解包:传递实参时,可以在序列类型的参数前面加上*,这样就会自动将序列中的元素依次作为参数传递


def func(a, b, c):
    print(a, b, c)


args = (1, 2, 3)
func(*args)  # 1 2 3
# 两个** 可以对字典解包,前提是参数名和key名需要一一对应
args = {'a': 100, 'b': 200, 'c': 300}
func(**args)    # 100 200 300

# 函数的返回值: return 关键字可以返回任意数据类型的对象(甚至函数),可以直接使用函数的返回值,或者使用变量来接收;
# return后面不加值或者不写return,则相当于return None;return 还可以用于结束函数
# break,continue,return 之间的区别
# fn 和 fn()的区别:一个是函数对象,一个是调用函数的结果


def sum(*nums):
    result = 0
    for i in nums:
        result += i
    return result


result = sum(1, 2, 3)
print(result)   # 6

# return 后面接函数对象的特殊情况(JAVA 无法这样)


def fn1():
    def fn2():
        print('this is fn2')
    return fn2


f = fn1()
f()  # this is fn2

2. 文档字符串(Python中的函数规范)

# 文档字符串:doc string,用于定义函数的说明
# help()是Python的内置函数,可以用于查询Python中函数的用法(但是可以使用插件自动提示~)
# help(print)

# 直接在函数的第一行使用```xxx```来书写函数说明

# 如果要写的更加规范和讲究,可以参考下面的Python 写法:
# 1. 在每个参数的后面使用:数据类型 来为函数的形参做出类型要求(但是无法进行强制检查,仅仅提示)
# 2. 然后在函数声明的末尾使用 -> 数据类型 来对该函数的返回值做出类型提示


def func1(a: int, b: bool, c: str='cris') -> str:
    '''
        函数的作用:
        参数a:
        参数b:
        参数c:
        返回值:
    '''
    print(a, b, c)  # 1 True cris
    return str(a) + str(b) + c


help(func1)  # 查看函数的说明
print(func1(1, True))    # 1Truecris

3. 函数的作用域和命名空间

# 函数变量的作用域(scope):在Python 中,变量一共有两种作用域:一种是全局作用域;一种是函数作用域
# 全局作用域:
# - 在程序执行的时候创建,程序执行结束后销毁
# - 所有函数以外的区域都是全局作用域
# - 在全局作用域中定义的变量,都属于全局变量,全局变量可以在程序的任意位置被访问

# 函数作用域:
# - 函数作用域在函数被调用时创建,调用结束后被销毁
# - 函数没调用一次,就会创建一个新的函数作用域
# - 在函数作用域中定义的变量,就是局部变量,只能在函数内部被访问

a = 10


def fn():
    print(a)


fn()    # 10

# 作用域支持就近原则以及层级嵌套(由内往外)


def fn1():
    a = 11

    def fn2():
        a = 12
        print("a:", a)
    fn2()


fn1()   # a:12

# 如果想要在函数内部修改全局作用域的变量,需要使用 global 关键字


def fn3():
    # 声明全局作用域的变量
    global a
    a = 'cris'  # 对全局作用域的变量进行修改
    print('cris=', a)


fn3()   # cris= cris
print('a=', a)  # a= cris

# 命令空间(namespace):命令空间指的就是变量存储的位置,每一个变量都需要存储到对应的命名空间中去
# 即每一个作用域都有其对应的命名空间:全局作用域对应的全局命名空间用来保存全局变量;函数作用域对应的局部命名空间用来保存局部变量
# 命名空间实质上就是一个字典,声明的变量都是以key-value 的形式保存到这个字典中

# locals()函数用于获取命名空间,在全局作用域调用获取的是全局命名空间;在函数作用域调用,获取的是函数的命名空间
space = locals()
print(type(space))  # <class 'dict'>
print(space['a'])   # cris

# 声明变量其实就是在往命名空间添加键值对
space['b'] = 123
# print(b)    # 123,不推荐使用这种方式定义变量,了解即可

# 可以通过global()在任意位置获取全局命名空间,不建议使用

猜你喜欢

转载自blog.csdn.net/cris_zz/article/details/83338299