Python入门学习笔记——4.函数基础

###############################################################
#1.认识函数

# 不能在函数定义前调用函数
# love()  #NameError: name 'love' is not defined

# 函数的定义格式
def love():
    print('i')
    print('love')
    print('you')

# 函数的调用
love()

# 函数的特征和注意
'''
1。函数定义后,不调用不执行
2。不能在函数定义前调用函数
3。函数的调用不受次数影响
4。函数的命名要遵守命名规范
    字母数字下划线,不能以数字开头
    严格区分大小写,不能使用关键字
    命名最好有意义,且不要使用中文
5。函数名不要冲突,冲突后会被覆盖
'''

###############################################################
#2.关于函数的参数

# 带有参数的函数,如何定义

# 在定义函数时,在小括号内可以定义行参(形式上的参数)
def love(w):
    print(f'i love you {w}')

# 调用带有行参的函数时,需要传递参数(实参)
# love('猩猩')
# love() # TypeError: love() missing 1 required positional argument: 'w'

# 带有多个参数的函数
def love(x,w):
    print(f'{x} i love you {w}')

# 函数定义了几个参数,那么在调用时就必须指定按顺序进行参数的传递
love('狗蛋','猫咪')

###############################################################
#3.函数中的参数类型

# 普通参数,默认参数,收集参数,命名关键字参数,关键字参数收集

# 普通参数 就是位置参数,也叫 顺序参数,也是必须传递的参数
# def func(x,y):
#     print(x,y)
# func(1,2)

# 默认参数
# 比如要求有三个参数,x,y,i,至少要传递两个,
# 那么这时最后一个参数就是默认参数,但是默认参数,需要在定义行参时,指定默认值
def func(x,y,i=100):
    print(x,y,i)

# 调用时传递了默认的参数,那么里面使用的就是传递的实参
# func(1,2,3)
# 调用时如果没有传递默认参数,那么就会使用默认值
# func(1,2)
# func()

# 收集参数
# 定义一个行参,专门收集多余的实参
# 或者理解为,不确定需要传递多少个实参,直接用一个行参来接收
# 在定义函数时,如果需要收集参数,那么这个行参前面需要加一个 * 号 例如 *args
# 接收的多余的参数,会存储在args中,形成一个元组

def func(a,b,x='+',*args):
    print(type(args))
    if x == '+':
        print('加法运算',args)
    else:
        print('减法运算',args)

func(1,2,'-',200,300,400)

###############################################################
#4.普通参数,默认参数,收集参数 *args

# 命名关键字参数
'''
1. 关键字参数定义在 收集参数 后面,
2. 关键字参数必须通过行参的名字来进行传递
'''

def love(a,b,c=3,*args,name):
    print(a,b,c)
    print(args)
    print(name)

# 在调用时,必须按照行参的名字进行参数的传递
love(1,2,4,5,6,7,8,9,name="amdin")
# love(1,2,4,5,6,7,8,9,'admin') X

# 普通函数
def love(age,name):
    print(name)
    print(age)

# love('abc')
# 在调用普通函数时,需要按照顺序进行参数的传递
# 也可以把普通函数的普通参数按照关键字参数进行传递,
love(name="aabbcc",age=123)

###############################################################
#5.关键字参数收集

# kw ==> keyword

def love(a,b,c=3,*args,name,age,**kwargs):
    print(a,b,c)
    print(args) # 普通收集参数,会把多余的参数收集成为 元组
    print(name,age)
    print(kwargs) # 关键字参数收集,会把多余的关键字参数收集为 字典

# love(1,2,3,112,123,name='aaa',age=222,sex='ccc',aa='aa',bb='bb')
# love(a=111,b=222,c=333,123,name='a',age=20,sex=0) # X

# 注意行参声明的位置
# 普通参数,默认参数,收集参数,关键字参数,关键字收集参数
'''
极少情况下会出现上面五种行参
一般情况下: 普通参数,收集参数,关键字收集参数
'''

###############################################################
#6.函数的返回值

'''
函数可以分为两类
    1。执行过程函数: 函数体内完成一定的功能既可,没有返回值
    2。具有返回值的函数: 函数体内完成一定的功能,并且返回一个结果到函数调用处
'''

'''
函数中可以使用 return 进行数据的返回
可以使用return 返回 任意内容或数据
return 会把返回值,返回到函数调用出
return 意味着函数的结束,return之后的代码不在执行
如果在函数中没有使用return  或者 return后面没有任何内容,那么默认返回 None
'''

# 在一个函数中,可以返回一些内容,也可以不返回

# 没有返回值的函数,或者理解为,没有指定返回内容,默认返回类 None
def love(a, b):
    print(f'{a} i love you {b}')

# r = love('奥特曼','小怪兽')
# print(r)

# None  是一个特殊的数据,表示什么都没有,空


# 如果需要在函数中指定返回内容,可以使用 return 关键字
def love(a,b):
    res = f'{a} i love you {b}'
    # 可以在函数体内,使用return 返回任意内容
    print(1)
    return res

# love('奥特曼','小怪兽')

# 调用带有返回值的函数时,函数中的返回值,会返回到函数调用处
# print(love('老鼠','猫咪'))
# r = love('狼','羊')
# print(r)


# 假设有这样一个需求,定义一个函数,完成两个数的计算,并把结果输出
# def jia(n1,n2):
#     res = n1+n2
#     print(res)
# jia(2,5)

# 需求改变,定义一个函数,完成两个数的计算,并把结果返回
def jia(n1,n2):
    res = n1+n2
    return res

r = jia(2,4)
print(r)

###############################################################
#7.变量的作用域

'''

局部变量
    函数内定义的变量,局部变量,在函数外不能使用

全局变量
    在函数内部使用 global 直接定义的变量,就是全局变量,函数内外都可以使用
    在函数外定义的变量,在函数内使用 global 关键字进行声明,那么也是全局变量

globals()  获取全局数据
locals()  获取当前作用域的数据

    在函数外定义的变量,函数可以访问,但是不能更改

数据类型的分类:
    可变数据类型:在函数外定义的变量,在函数可以使用,
        列表和字典
    不可变数据类型:在函数外定义的变量,在函数内只能访问,不能使用其它操作
'''

num = 10
varlist = [1,2,3]
vardict = {'a':'a','b':'b'}

def func():
    global num
    print(num) # 在函数内可以获取函数外部的变量
    num += 20 # 在函数内不能直接更改函数外的变量

    # print(varlist)
    # varlist[2] = 'aa'

    # print(vardict)
    # vardict['a'] = 'aa'

    # 函数内定义的变量 局部变量
    love = 20
    love += 1
    # print(love)

    # 在函数内部使用 global关键字定义的变量就是全局变量
    global live
    live = 'iliveyou'

    # 在函数内部使用 global和locals
    # print(globals())
    # print(locals())

func()
# print(num)
# print(love) # 函数内定义的变量,在函数外不能使用
# print(varlist)
# print(vardict)

# print(live)
# live = 'live'
# print(live)


# 在函数外使用函数
# globals() 获取全局变量数据
# locals()  获取当前作用域的变量数据
# print(globals())
# print(locals())
# 问:为什么上面两个函数的结果一模一样
# 因为当前区域就是全局区域


# 不光变量有作用域,函数一样也有相同的作用域

def outer():
    print('this is outer function...')
    # 在函数内定义的函数,称为 局部函数,函数外无法使用
    def inner():
        print('this is inner function...')
    inner()

outer()
# inner()

###############################################################

#8.nonlocal关键字及函数文档

# 变量和函数都有作用域
# 在内函数中如何使用上一层函数中的局部变量?

'''
在内函数中如果想使用外层函数的变量,那么需要使用 nonlocal 关键字 引用
可以引用上一层函数中定义的局部变量,但依然不能提升为全局变量

'''


# 定义一个外层函数
def outer():
    '''
    这里是让你些当前函数的文档说明的。
    需要说明当前函数的作用,
    如果当前函数还有行参,那么也需要对行参进行一一说明
    name: 这个是一个name参数,有什么作用。。。
    age : 这个表示当前的一个年龄
    :return:  此处说明当前函数的返回值。。。
    '''
    # 外函数的局部变量
    num = 10
    # 内函数,局部函数,在函数的内部定义的函数
    def inner():
        # nonlocal 关键字在局部函数中使用,
        nonlocal num # 可以引用上一层函数中定义的局部变量,但依然不能提升为全局变量
        num += 1
        print(num)
    inner()


outer()

# print(num)


# 关于函数的文档
print(globals())

print(__name__) # 获取当前脚本的文件名,
print(__doc__) # 获取当前脚本的说明文档
# print(outer.__doc__) # 获取当前函数的说明文档
'''
魔术变量
__name__  ==> 当前脚本如果作为主程序,那么值是 __main__,如果是当做一个模块,在另外一个脚本中引用去使用,那么值就是当前文件的名字
__doc__   ==> 当前脚本的文档说明 在当前脚本当中的第一个 三引号注释就是当前脚本的说明文档


{
    '__name__': '__main__', 
    '__doc__': '\n在内函数中如果想使用外层函数的变', 
    '__package__': None,
     '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x110444350>, 
     '__spec__': None, 
     '__annotations__': {}, 
     '__builtins__': <module 'builtins' (built-in)>, 
     '__file__': '/Users/yc/Desktop/code/8.nonlocal关键字.py', 
     '__cached__': None, 'outer': <function outer at 0x1104938c0>
}

'''
###############################################################



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值