python基础(二)

函数

函数定义

函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段。

python函数定义规则:

python 复制代码
def my_max(a,b):   #定义函数用def关键字开头,函数名-》my_max ()定义参数   
    if a>b:        #函数体以:开始并进行缩进
        return a   #结束函数,选择性返回一个值给调用方,不带return相当于返回None
    else: 
        return b
print(my_max(3,4)) #函数名()  函数调用

函数参数

python 复制代码
def modify(a): 
    print(hex(id(a))) #0x7ff92c79e328 
    a=10              #传入不可变对象相当于传入新的a,不改变原传入对象的值
    print(hex(id(a))) #0x7ff92c79e328
    print(a)          #10
a=1
print(hex(id(a)))     #0x7ff92c79e448
modify(a)     
print(a)              #1
def modify(lis):      #可变类型对象的测试,原对象传过来修改也影响了原对象
    lis.append([1,2])
    print('list in func ',lis) #[1, 2, 3, [1, 2]]
    print(hex(id(lis)))   #0x22215e11f00  函数内地址与函数外一样
mylis=[1,2,3]
print(hex(id(mylis)))   #0x22215e11f00
modify(mylis)
print('out funct ',mylis)  #[1, 2, 3, [1, 2]]

参数类型

|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 必需参数 | 必需参数须以正确的顺序传入函数,调用时的数量必须和声明时的一样。 |
| 关键字参数 | 函数调用使用关键字参数来确定传入的参数值,使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。 |
| 默认参数 | 调用函数时,如果没有传递参数,则会使用默认参数,传递了自然用传递的参数 |
| 不定长参数 | 在形参前边加上一个*,这样这个形参将会获取到所有的实参,并将所有的实参保存到一个元组中,*形参只能接收位置参数,而不能接收关键字参数。**形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中。字典的 key 就是参数的名字,字典的 value 就是参数的值。**形参只能有一个,并且必须写在所有参数的最后。 |

python 复制代码
#必须参数
def show(str):
    print(str)
    return
# show() #TypeError: show() missing 1 required positional argument: 'str'
show('2') 

#关键字参数
def show1(name,age):
    print(name,age)
    return
show1(age=10,name='AC') 
show1(name='AC',age=10)
show1('AC',6)
#默认参数
def show2(name,age=10,add='here'): #与C++一样,一旦有了默认值后面的都要有
    print(name,age,add)
    return
show2(age=2,name='AC')
show2(name='AC')
#不定长参数
def show3(*name):
    print(name,type(name))     #('ac', 'li', 'io')  <class 'tuple'>
show3('ac','li','io') 
def show4(arg,*name):
    print(arg)    
    print(name)
show4(1)    #1 ()
show4(1,2)  # 1  (2,)
show4(1,2,4) #1 (2,4)
def show5(arg,*name,age): #age 必须使用关键字参数
    print(arg,name,age)    
show5(1,2,3,age=5) #1 (2, 3) 5
def show6(arg, name, **a): #** 形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中
    print('a =', a, type(a)) #a = {'x': 3, 'y': 4} <class 'dict'>
    print(arg,name)
show6(arg=1,name=2,x=3,y=4)
show6(1,2,x=3,y=4)  #a = {'x': 3, 'y': 4} <class 'dict'>
#强制位参数
def show7(a,b,/,c,d,*,e):
    print(a,b,c,d,e)
show7(1,2,3,d=4,e=5)
#show7(1,b=2,c=3,d=4,e=5) #b 不能使用关键字参数的形式
#show7(1,2,3,4,5) #e 必须使用关键字参数的形式

匿名函数

python 复制代码
#匿名函数定义及调用
func=lambda x,y:x+y   #lambda 生成一个函数对象,参数x,y 返回值x+y
func(1,2) #3  函数对象赋给了func, 使用变量调用函数和普通函数无异
#匿名函数作为返回值
def build(x,y):
    return lambda: x*x+y*y
build(2,3)() 

高阶函数

函数式编程:是一种编程范式,一种结构化编程(子程序或者程序代码块),思想在于尽量协程一系列嵌套的函数调用,它的特点是允许把函数作为参数传给另一个函数,还可以返回一个函数,python并非函数式编程语言,但是支持一些函数式编程构建(匿名函数、BIF(filter/map)、偏函数)本质上通过封装对象实现函数式编程。

内置高阶函数map、filter、reduce

python 复制代码
# filter函数的使用
def is_odd(x):
    return x % 2 == 1
 
# 使用filter过滤出列表中的奇数
list_of_numbers = [1, 2, 3, 4, 5, 6]
filtered_numbers = filter(is_odd, list_of_numbers)
print(list(filtered_numbers))  # 输出: [1, 3, 5]
result = list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5]))
print(result)  # [2, 4]
 
# map函数的使用
def square(x):
    return x * x
 
# 使用map计算列表中每个数的平方
list_of_numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(square, list_of_numbers))
print(squared_numbers)  # 输出: [1, 4, 9, 16, 25]
result = list(map(lambda x: x * x, [1, 2, 3, 4, 5]))
print(result)  # [1, 4, 9, 16, 25]
 
# reduce函数的使用(Python 3中需要从functools模块导入)
from functools import reduce
 
def add(x, y):
    return x + y
 
# 使用reduce进行求和
list_of_numbers = [1, 2, 3, 4, 5]
result = reduce(add, list_of_numbers)
print(result)  # 输出: 15
result = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(result)  # 15

装饰器

装饰器是一种特殊类型的函数,它可以修改或增强其他函数的功能,而无需更改原始函数的源代码。装饰器本质上是一个接收函数作为参数的函数,它返回一个新的函数或者修改过的原函数。

python 复制代码
#装饰器
def decorator(func):
    def wrapper():
        print("Before func_to_decorate called.")
        func()
        print("After func_to_decorate called.")
    return wrapper
@decorator
def func_to_decorate():
    print("Function to decorate.")
func_to_decorate()

闭包

闭包(closure)是一个函数和它所引用环境的组合。在Python中闭包通常是指在函数内部定义的函数,该内部函数可以访问外部函数的局部变量,即使外部函数已经返回。闭包的一个常见用途是创建可以记住某些状态的函数。

python 复制代码
#闭包
# 默认情况下,内部函数不能直接修改外部函数的局部变量,除非它使用 nonlocal 关键字声明
def outer_function(x):
    print('out_func',x) #2
    def inner_function(y):
        print('inner ',y) #3 当double(3)传入
        return x * y 
    return inner_function
 
double = outer_function(2)
print(double(3))  # 6

变量的作用域

作用域就是一个 Python 程序可以直接访问命名空间的区域,在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
  • G(Global):当前脚本的最外层,比如当前模块的全局变量。
  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

搜索规则顺序: L --> E --> G --> B在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal

global关键字用于在函数内部声明变量为全局变量。当需要在一个函数内修改全局作用域中的变量时,就需要使用global关键字。

nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量。它主要用在嵌套函数中,当需要修改嵌套作用域内的变量时使用nonlocal。

python 复制代码
z=30
def out_fun():
    y=20
    global z #表明全局变量被修改
    z=39
    print("global z: ",z) #39 if no global 39
    print(len("sf"))  #2 内建函数
    def func():
        x=10 #局部嵌套变量
        nonlocal y #内存修改了外层变量
        y=24
        print("local x: ",x)  #10
        print("Local y: ",y)  #24 if no nonlocal 24
        print("global z: ",z) #39 if no global 39
    func()
    #print(x) #外部不可以调用
    print("out local y: ",y) #24 if no nonlocal 20
out_fun()
print("global z: ",z) #39 if no global 30

偏函数

functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

python 复制代码
from functools import partial
def func(a, b, c):
    return a + b + c
# 创建一个新的偏函数,预先绑定a=1和b=2
new_func = partial(func, a=1, b=2)
# 现在可以调用new_func并只提供c的值
result = new_func(c=3)  # 返回 6

模块-包

模块:是一个包含所有你定义的函数和变量的文件,以.py后缀结尾。模块可以被别的程序引入和使用其中的函数功能。

包Package: 即文件夹,传统包里有一个 __init__.py 文件。可以为空文件,但一定要有该文件,它是包的标志性文件,在需要情况下可以在里面进行一些包的初始化工作。

python 复制代码
#模块
import math  #导入Python标准库中的math模块
print(math.sqrt(4))
from math import sqrt #也可以导入模块中的特定函数或对象如只导入sqrt函数
print(sqrt(3))
#模块重载 Python解释器会在模块第一次导入时执行模块文件。如果模块文件发生了改变
# 必须先卸载模块,然后再重新导入,以便获取最新的代码。可以使用importlib.reload()
# 函数来卸载并重新导入模块:
# import importlib
# import my_module
#  # 对my_module.py做一些修改
# importlib.reload(my_module)

#包,创建包需要一个名为__init__.py的文件,它可以为空,但其存在表明这个目录
#应被视为一个包。如创建一个名为my_package的包:
#my_package/
#    __init__.py
#    my_module.py
#__init__.py文件可以包含初始化代码和要导入的对象。例如,在my_package/__init__.py
# 中导入my_module中的my_function:

# my_module.py    在my_module.py中,可以定义一个函数
# def my_function():
#     print("Hello from my_package!")
#from my_package.my_module import my_function
#my_function()  # 输出:Hello from my_package!

#包的导入 分为相对导入和绝对导入
#相对导入(以点开头),from .my_module import my_function
# 或绝对导入(直接指定模块或子包的名称) from my_package.my_module import my_function

#包版本管理
#每个包都可以包含一个名为__version__.py的文件,用于指定包的版本。这可以通过
#导入pkg_resources模块来检查
相关推荐
苏言の狗1 分钟前
Pytorch中关于Tensor的操作
人工智能·pytorch·python·深度学习·机器学习
用余生去守护24 分钟前
python报错系列(16)--pyinstaller ????????
开发语言·python
数据小爬虫@28 分钟前
利用Python爬虫快速获取商品历史价格信息
开发语言·爬虫·python
向宇it30 分钟前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
莫名其妙小饼干1 小时前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql
是Dream呀1 小时前
Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络
网络·python·神经网络
菜狗woc1 小时前
opencv-python的简单练习
人工智能·python·opencv
十年一梦实验室1 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
最爱番茄味1 小时前
Python实例之函数基础打卡篇
开发语言·python
程序猿000001号1 小时前
探索Python的pytest库:简化单元测试的艺术
python·单元测试·pytest