python函数学习

本文介绍了Python中的函数概念,包括自定义函数、普通函数、局部函数、闭包和lambda表达式的用法。详细讨论了函数参数,如默认参数、可变参数以及如何通过`functools.partial`创建偏函数。此外,还讲解了变量的作用域,如全局变量、局部变量以及如何在函数内部修改全局变量。最后,提到了函数的返回值、map、filter、reduce函数以及函数注解的使用。
摘要由CSDN通过智能技术生成
import threading
import time
from functools import partial


# Python 函数可分为:自定义函数和系统函数
# Python 函数也支持 普通函数、局部函数、闭包 和 lambda 表达式四种形式

# 求两个数之间的和
def getSum(a, b):
    maxVal = max(a, b)
    minVal = min(a, b)
    res = 0
    # range(start, stop[, step]) 从[start, stop)之间的步长为step的一系列元素, start默认是从0开始,可不填, step默认为1,可不填
    for i in range(minVal, maxVal + 1):
        res += i
    return res


# 两个数的最大公约数
def gcdNormal(x, y):
    n = 0
    if x > y:
        n = y
    else:
        n = x
    for i in range(n, 0, -1):
        print(i)
        if x % i == 0 and y % i == 0:
            return i
    return 1


# 字符串	值传递
# 数字	值传递
# 元组	值传递
# 列表	引用传递
# 字典	引用传递

def changeStr(s):
    s = "1234"


def changeNum(num):
    num = 1234


def changeTup(tup):
    tup = ("1234", 1234)


def changeList(lis):
    lis.append("1234")


def changeDict(dic):
    dic["345"] = 345


def testRef():
    str0 = "123"
    num0 = 123
    tup0 = ("123", 123)
    list0 = ["123", 123]
    dict0 = {"123": 123, "234": 234}
    changeStr(str0)
    changeNum(num0)
    changeTup(tup0)
    changeList(list0)
    changeDict(dict0)
    print("str0", str0)  # '123'
    print("num0", num0)  # 123
    print("tup0", tup0)  # ('123', 123)
    print("list0", list0)  # ['123', 123, '1234']
    print("dict0", dict0)  # {'123': 123, '234': 234, '345': 345}


# 默认参数
# def func_name(param1 = value1, param2 = value2){
#     # 执行语句...
#     return val
# }
# func_name(p1, p2)
# func_name(p1)
# func_name()
def defaultParamTest(param1=1, param2='2'):
    print('param1', param1, 'param2', param2)


def testDefaultParam():
    defaultParamTest()
    defaultParamTest(param1=11)
    defaultParamTest(param2='22')
    defaultParamTest(param1=11, param2='22')


# Python 中函数的可变参数又被称为不定长参数,Python 中的可变参数不是必须是函数的最后一个参数
# 但如果不是函数的最后一个参数,那么普通参数必须使用关键字参数的形式传值
# 可变参数 还可以支持以 字典 的形式进行传递
# Python 函数的返回值不需要在函数的签名上体现,只需要在函数体里面直接使用 return 语句返回即可
# python使用元组的形式返回多个值
def testParam1():
    def my_sum(*args, prefix):
        res = 0
        for arg in args:
            res += arg
        print(prefix, res)

    my_sum(1, 2, 3, 4, 5, prefix="Sum =")

    def info(prefix, **args):
        print(prefix)
        for key, value in args.items():
            print(key, "--->", value)

    info(Site="HaiCoder", Module="Python", prefix="Info")


def eng_days():
    return "Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"


def print_info(prefix, info):
    print(prefix, info)


# 偏函数,简化函数
# 将所要承载的 函数 作为 partial() 函数的第一个 参数,原函数的各个参数依次作为 partial() 函数后续的参数,除非使用关键字参数
# 当函数的参数个数太多,需要简化时,使用 functools.partial 可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单
# 语法
# from functools import partial
# partial_func = partial(func, *args, **kwargs)
def testPartialFunc():
    print_demo1 = partial(print_info, "demo1 =")
    print_demo2 = partial(print_info, "demo2 =")
    print_demo1("demo111")
    print_demo2("demo222")


# 在函数内部定义全局变量
def globalValue():
    global info
    info = "globalValue"


def testGlobalValue():
    globalValue()
    print("info", info)


def testMultiReturnVal():
    days = eng_days()
    print("Type =", type(days))
    print("Days =", days)
# globals()
# 以字典的形式,返回全局范围内所有的变量
# 其中字典的 key 为变量名,字典的 value 为变量的值
#
# locals()
# 以字典的形式,返回当前作用域内所有的变量
# 其中字典的 key 为变量名,字典的 value 为变量的值
#
# vars()
# 以字典的形式,返回在指定对象范围内所有的变量
# 如果不传入 object 参数,vars() 和 locals() 的作用完全相同
#
# Python globals与locals函数区别
# locals() 函数总是以字典的形式返回当前作用域内所有的变量
# 如果在全局作用域调用 locals() 函数,那么获取的就是全局作用域的所有变量
# 如果在局部作用域调用 locals() 函数,那么返回的就是局部作用域的所有变量
# globals() 函数无论在哪里执行,总是获取的是全局作用域里的所有变量
#
# 一般来说,使用 locals() 和 globals() 获取的字典形式的变量只应该被访问,不应该被修改
# 但实际上不管是使用 globals() 还是使用 locals() 获取的全局范围内的变量,都可以被修改
# 这种修改会真正改变全局变量本身,但通过 locals() 获取的局部变量
# 即使对它修改也不会影响局部变量
#
# g_info = "demo"
# def print_info():
#     # 使用 globals() 函数,获取全局作用域所有变量
#     g_vars = globals()
#     print("print_info_g_g_vars =", g_vars["g_info"])
#     # 使用 locals() 函数,获取当前作用域所有变量
#     t_info = "hello"
#     v_vars = locals()
#     # print("print_info_v_g_info =", v_vars["g_info"]) 报错
#     print("print_info_v_t_info =", v_vars["t_info"])
#
# 全局变量默认可以在所有的函数内被访问
# 但如果在函数中定义了与全局变量同名的变量时,会发生局部变量隐藏全局变量的情形
#
# 如果局部变量隐藏了全局变量,那么当再次访问全局变量时,程序会报错,会说找不到该变量
# 因为该全局变量被局部变量隐藏。
#
# 当局部变量与全局变量重名时,可以在函数内部使用 global 关键字来说明
# 在函数内部使用的是全局变量,而不是再次定义一个局部变量
#
# if __name__ == "__main__":
#     print()
#     vars = globals()
#     print_info()
#     print("main_global_vars =", vars["g_info"])
#
#     vars = locals()
#     print_info()
#     print("main_local_vars =", vars["g_info"])

# varname = "123"
# def func():
#     print(varname)  # 函数 func 里面定义的局部变量 varname 隐藏了全局变量 varname,程序报错
#     varname = "456"
#
# if __name__ == "__main__":
#     func()
#     print(varname)


# site = "Demo"
# def func():
#     global site  # 函数中修改全局变量
#     print("In Func Site =", site) # Demo
#     site = "demo"
#
# func()
# print("Global Site =", site)      # demo

#
# site = "Demo"
# def func():
#     print("In Func Site =", globals()["site"]) # Demo
#     site = "demo"  # 局部修改
#
# func()
# print("Global Site =", site) # Demo

#  函数中定义了与全局变量同名的变量
# site1 = "Demo1"
# site2 = "Demo2"
# def testDupName():
#     # print("testDupName before change =", site1) 无法引用,因为下面对site1进行了修改
#     # globals 关键字访问变量 site1 的值,设置完就可以引用
#     # site1变为局部变量,修改后不会对全局产生影响
#     print("testDupName before globals change =", globals()["site1"])
#     print("testDupName before change =", site2)
#     site1 = "demo1"
#     # site2 = "demo2" # 编辑全局变量就报错
#     print("testDupName after change =", site1)
#
#
# print("main before testDupName, site1 =", site1)
# testDupName()
# print("main after testDupName, site1 =", site1)
# print("main after testDupName, site2 =", site2)

# 函数内部定义的变量与局部函数定义的变量重名
# def func():
#     varname = "123"
#     def func_inner():
#         print(varname) # 局部函数 func_inner 里定义的变量 varname 隐藏了函数 func 的局部变量 varname,导致报错
#         varname = "456"
#     func_inner()

# 函数内部定义的变量与局部函数定义的变量重名的解决办法
# def func():
#     site = "Demo"
#     def func_inner():
#         nonlocal site
#         print("In Func Site =", site)  # Demo
#         site = "demo"
#
#     func_inner()
#     print("nonlocal Site =", site)   # demo
# func()

# 闭包
# 与局部函数不同之处在于,闭包中外部函数返回的不是一个具体的值,而是一个函数
# 一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继续执行调用
#
# 闭包的记忆功能
# 被捕获到闭包中的变量让闭包本身拥有了记忆效应,闭包中的逻辑可以修改闭包捕获的变量,变量会跟随闭包生命期一直存在
#
# 局部函数引用到函数外的 n,因此这个局部函数就和 n 形成了一个整体,构成了闭包
# 反复调用 f 函数时,因为 n 只初始化一次,因此每调用一次就累计一次
# Python 闭包记忆效应,实现累加
# def add_upper():
#     n = 20
#     def add(x):
#         nonlocal n
#         n = n + x
#         return n
#     return add
# f = add_upper()
# print("闭包返回:", f(1))  # 21
# print("闭包返回:", f(2))  # 23
# print("闭包返回:", f(3))  # 26
#
# Python闭包,实现判断文件后缀
# def make_suffix(suffix):
#     def func_suffix(name):
#         if not name.endswith(suffix):
#             return name + suffix
#         return name
#     return func_suffix
# f = make_suffix(".jpg")
# print("FileName =", f("sea"))  # sea.jpg
# print("FileName =", f("sun.jpg"))  # sun.jpg

# lambda表达式
# lambda [parameter_list] : expression
# lambda [parameter_list, param=val] : expression
# funcs = [lambda x, n=n: x+n for n in range(val)]
#
# sum = lambda x, y : x + y
# print("lambda res =", sum(512, 512))
#
# # lambda 表达式参数是运行时绑定的
# add = lambda y : x + y
# x = 20
# print("lambda add =", add(20))
# print("lambda add =", add(30))
#
# sum = lambda x, y=100: x + y # y有默认值100
# print("lambda res =", sum(512, 512))  # 1024
# print("lambda res =", sum(512))       # 612
#
# x = 10
# add = lambda y, x=x : x + y
# x = 20
# # lambda 表达式参数是运行时绑定的
# print("lambda add =", add(20))    # 30
# print("lambda add =", add(30))    # 40
#
# funcs = [lambda x, n=n: x+n for n in range(3)] # 参数x和n,x是外部传入的,n是生成的,返回[x+0, x+1, x+2]
# for f in funcs:             # 遍历 [x+0, x+1, x+2]
#     print("Val =", f(1))    # 返回 [1,2,3]

# map函数
# map(function, iterable, ...)
# function	需要传入的函数,这个函数可以是内置的,也可以是自己定义,或者是匿名函数
# iterable	一个可迭代对象,如 列表,字符串,元祖,字典 等
# 计算列表[1, -2, -3]的绝对值
# map_abs = map(abs, [1, -2, -3])
# for val in map_abs:
#     print("map_abs =", val)
#
# 计算立方值
# def cube(x):
#     return x*x*x
# map_cube = map(cube, [1, 2, 3])
# for val in map_cube:
#     print("map_cube =", val)
#
# map函数是lambda表达式
# map_vals = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
# for val in map_vals:
#     print("map_val =", val)

# filter(function, iterable)
# filter 函数会根据传入的函数对指定序列做过滤
# function 返回true的保留,function返回 false的丢弃
# def is_even(num):
#     return num % 2 == 0
# filter_even = filter(is_even, [2, 5, 6])
# for val in filter_even:
#     print("filter_even =", val)  # 2、6
#
# 返回1~50之间能被14整除的数
# def filter_num(x):
#     if x % 2 == 0 and x % 7 == 0:
#         return True
#     return False
# filter_n = filter(filter_num, range(1, 51))
# for val in filter_n:
#     print("filter_n =", val)
#
# lambda表达式
# filter_vals = filter(lambda x: x >= 7, [1, 3, 5, 7, 9])
# for val in filter_vals:
#     print("filter_val =", val)  # 7、9

# reduce()
# 对传入的 参数 序列中的每一个元素进行累积操作
# 用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作
# 得到的结果再与第三个数据用 function 函数运算
# 重复操作,直到所有的元素都处理完毕后得到一个结果,并返回
#
# 对列表每个元素累积后的返回值
# from functools import reduce
# def add(num1, num2):
#     return num1 + num2
# reduce_res = reduce(add, [1, 2, 3, 4, 5, 6])
# print("reduce_res =", reduce_res)  # 21
#
# lambda表达式
# from functools import reduce
# reduce_res = reduce(lambda x, y: x+y, [1, 2, 3, 4, 5, 6])
# print("reduce_res =", reduce_res)    # 21

# 函数注解
# def func(param1:param1 note, param2:param2 note=default val)->return val note:
# 获取函数注解信息详解
# print(func_name.__annotations__)
# def circle(r:'圆的半径')->'返回圆的半径':
#     return 3.14 * 2 * r
# circle_res = circle(10)
# print("circle_res =", circle_res)   # circle_res = 62.800000000000004
# print(circle.__annotations__)       # {'r': '圆的半径', 'return': '返回圆的半径'}
#
# def my_sum(num1:'开始的数', num2:'结束的数'=100)->'开始数到结束数所有数的和':
#     res = 0
#     for i in range(num1, num2+1):
#         res = res + i
#     return res
# sum_res = my_sum(1, 50)
# print("sum_res =", sum_res)       # 1275
# sum_res = my_sum(1)
# print("sum_res =", sum_res)       # 5050
# print(my_sum.__annotations__)     # {'num1': '开始的数', 'num2': '结束的数', 'return': '开始数到结束数所有数的和'}

# Python 是一种解释型脚本语言
# 和 C++、Golang 等语言不同, C++、Golang 等程序都是从 main 函数开始执行
# Python 程序是从开始到结尾顺序执行
# Python 中的 main() 函数只有当该 Python 脚本直接作为执行程序时才会执行
# 当该 Python 脚本被作为模块被导入时,其中的 main() 函数将不会被执行
# 一方面,main 函数是所有执行程序的入口
# 另一方面,Python 的解释器是顺序执行脚本的并且不会调用任何不属于程序本身的代码和函数
#
# 只要创建了一个模块,也就是一个 .py 文件,这个模块就有一个内置属性的 name ,该模块的 name 的值取决于如何应用这个模块
# 如果直接运行该模块,那么 __name__ 的值就是 "__main__",如果 import 一个模块,那么模块 name 的值通常为模块文件名
# if __name__ == '__main__':
#     main()
# 上述代码的意思就是,如果模块是被直接运行的,则 main 代码块会被运行,如果该模块是被 import 导入的,则代码块不被运行

# 命令行参数
# 命令行参数解析共有三种方法,分别为:使用 sys 模块,使用 getopt 模块和使用 argparse 模块
# import sys
# argc = len(sys.argv)
# print("Cmd line count =", argc)
# for argv in sys.argv:
#     print("Cmd line :", argv)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值