open 函数是 Python 中用于打开文件的内置函数,它返回一个文件对象,该对象提供了许多用于文件操作的方法,如读取、写入、追加等。使用 open 函数时,你需要指定文件名和模式(如只读、只写、追加等)。
读取文件
# 打开文件并读取内容
with open('example.txt', 'r') as file:
content = file.read()
print(content)
写入文件
# 打开文件并写入内容
with open('example.txt', 'w') as file:
file.write('Hello, world!')
dump
import json
data = {'name': 'John', 'age': 30, 'city': 'New York'}
json_str = json.dumps(data)
print(json_str) # 输出: {"name": "John", "age": 30, "city": "New York"}
dump
import json
data = {'name': 'John', 'age': 30, 'city': 'New York'}
with open('data.json', 'w') as f:
json.dump(data, f)
# 现在data.json文件包含了序列化后的数据
总结
dumps:将Python对象编码成字符串。
dump:将Python对象直接写入文件或类似文件对象。
虽然open函数本身不提供dump和dumps方法,但你可以结合使用open函数和json或pickle等模块的dump和dumps函数来实现数据的序列化和反序列化。
loads() 函数
loads() 函数的全称是 “load string”,它的作用是将JSON格式的字符串转换成Python的数据结构。这个函数不需要打开文件,因为它直接从字符串中读取JSON数据。
用法示例:
import json
json_str = '{"name": "John", "age": 30, "city": "New York"}'
data = json.loads(json_str)
print(data) # 输出: {'name': 'John', 'age': 30, 'city': 'New York'}
print(type(data)) # 输出: <class 'dict'>
在这个例子中,json_str 是一个包含JSON数据的字符串,json.loads(json_str) 将这个字符串转换为了Python的字典(dict)类型。
load() 函数
load() 函数的全称是 “load from a file-like object”,它的作用是从一个文件对象(或者任何实现了.read()方法的对象)中读取JSON数据,并将其转换为Python的数据结构。
用法示例:
首先,假设你有一个名为data.json的文件,内容如下:
{
"name": "John",
"age": 30,
"city": "New York"
}
然后,你可以使用load()函数来读取这个文件并转换数据:
i
mport json
with open('data.json', 'r') as f:
data = json.load(f)
print(data) # 输出: {'name': 'John', 'age': 30, 'city': 'New York'}
print(type(data)) # 输出: <class 'dict'>
在这个例子中,open(‘data.json’, ‘r’) 打开了文件data.json,并将其作为文件对象f传递给json.load(f)。json.load(f)读取文件内容,并将其转换为Python的字典。
总结
loads() 用于将JSON格式的字符串转换为Python数据结构。
load() 用于从文件或其他文件对象读取JSON数据,并将其转换为Python数据结构。
这两个函数是处理JSON数据时非常有用的工具,但它们的应用场景不同。
Pickle的基本用法
- 序列化
序列化是指将Python对象转换为一个字节流的过程。Pickle模块提供了dumps()函数和dump()函数用于序列化。
dumps(obj, protocol=None, *, fix_imports=True): 将对象obj序列化为字节对象。protocol参数指定序列化使用的协议版本,默认值为None,表示使用最高版本的协议。
dump(obj, file, protocol=None, *, fix_imports=True): 将对象obj序列化到文件对象file中。这里的file必须是一个具有write()方法的对象,且文件应以二进制写模式(‘wb’)打开。
2. 反序列化
反序列化是指将字节流转换回原来的Python对象的过程。Pickle模块提供了loads()函数和load()函数用于反序列化。
loads(bytes_object, *, fix_imports=True, encoding=‘ASCII’, errors=‘strict’): 将字节对象bytes_object反序列化为Python对象。
load(file, *, fix_imports=True, encoding=‘ASCII’, errors=‘strict’): 从文件对象file中读取字节流并反序列化为Python对象。这里的file必须是一个具有read()和readline()方法的对象,且文件应以二进制读模式(‘rb’)打开。
Pickle的优缺点
优点
灵活性:Pickle可以序列化几乎所有的Python对象,包括自定义对象、集合类型(如列表、字典、集合等)以及原生数据类型(如整数、浮点数、字符串等)。
便捷性:Pickle提供了一种简单的持久化机制,可以将对象直接保存到文件中,而不需要先将它们转换为字符串或其他格式。
效率:Pickle使用二进制格式存储数据,相对于文本格式(如JSON)来说,可以更加紧凑和高效。
缺点
可读性差:Pickle序列化后的数据是二进制格式,人类无法直接阅读。
安全性问题:由于Pickle可以反序列化任意对象,因此从不受信任的来源加载Pickle数据可能会带来安全风险。
版本兼容性问题:在不同版本的Python之间,Pickle数据的兼容性可能会存在问题。
跨语言性:Pickle数据只能被Python程序读取和写入,无法与其他语言进行数据交换。+
python的作用域
在Python中,变量的作用域是一个重要的概念,它决定了变量在程序中哪些部分可见和可访问。
全局作用域
global关键字:
作用:在函数内部声明变量为全局变量,以便在函数内部修改全局变量的值。
使用场景:当需要在函数内部修改全局变量时。
a = 10
print(a)
def kk():
global a
print(a)
a = 15
kk()
print(a)
局部作用域
局部作用域指的是在函数内部定义的变量,这些变量只能在函数内部被访问和修改。
a = 30
print(a)
def j():
a = 10
print(a)
def k():
nonlocal a
a = 20
print(a)
return j
r = j()
r()
print(a)
a = 25
print(a)
递归函数
递归函数是一种在函数体内调用自身的函数。这种调用方式允许函数通过解决更小或更简单的子问题来逐步解决复杂问题。+
首先是递归出口,这是结束递归函数的方式
阶乘
阶乘函数是一个很好的递归函数示例。阶乘的定义是:n! = n * (n-1) * (n-2) * … * 1,其中0! = 1。
def factorial(n):
# 基准情形
if n == 0:
return 1
# 递归步骤
else:
return n * factorial(n-1)
print(factorial(5)) # 输出: 120
斐波那契数列
斐波那契数列是另一个递归函数的常见示例。斐波那契数列是这样一个数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …,其中每个数是前两个数的和。
def fibonacci(n):
# 基准情形
if n <= 1:
return n
# 递归步骤
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 输出: 55
且递归函数有限制,递归的最大次数默认为1000
可以通过使用sys模块下的sys.getrecursionlimit()查看最大限制,这个限制sys.setrecursionlimit()可以改变
import sys
print(sys.getrecursionlimit())
sys.setrecursionlimit(3000)
print(sys.getrecursionlimit())
递归的注意事项
效率:递归函数有时效率较低,因为它们可能重复计算相同的子问题。这可以通过使用记忆化(memoization)或动态规划来优化。
栈溢出:如果递归太深,可能会导致调用栈溢出。这通常发生在没有正确设置基准情形或递归步骤没有向基准情形推进时。
理解难度:递归函数对于初学者来说可能较难理解,因为它们涉及函数自身的调用。
闭包函数
定义
闭包函数是指能够访问另一个函数作用域中变量的函数。当内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和其他内部函数时,如果其中一个这样的内部函数在包含它们的外部函数之外被调用,就会形成闭包。
def fun1():
print("fun1")
dates =[1, 2, 3, 4, 5]
def fun2():
print("fun2", dates)
return fun2
r = fun1()
r()
特性
作用域封闭:闭包函数可以访问外部函数的局部变量,即使外部函数已经执行完毕。这些局部变量在闭包函数的作用域中被封闭,外部无法直接访问,但闭包函数内部可以访问和修改它们。
延长变量生命周期:通常情况下,函数的局部变量在函数执行完毕后会被销毁。但在闭包中,这些变量的生命周期会被延长,因为它们仍然被闭包函数所引用。
避免全局作用域污染:通过闭包,可以在函数内部创建私有变量和方法,避免全局作用域的污染,提高代码的模块性和封装性。
匿名函数
匿名函数,也称为闭包函数(closures)或lambda函数(在某些编程语言中),是一种没有指定名称的函数。它们的主要特点是可以在需要函数的地方直接定义和使用,而不必事先声明函数名。这种特性使得匿名函数在编程中非常灵活,特别适用于一次性使用的简单函数或作为回调函数使用。
匿名函数的特点
无需定义函数名:匿名函数没有函数名,因此可以直接在需要的地方定义和使用,避免了命名冲突或命名困扰。
一次性使用:匿名函数通常用于一次性使用的情况,不需要事先定义函数名,避免了定义函数的繁琐过程。
简化代码:匿名函数可以将一些简单的函数功能直接写在一行代码中,简化了代码的编写和阅读。
函数即表达式:匿名函数的定义形式和表达式非常接近,可以直接将其作为表达式使用,简化了代码的结构和逻辑。
支持函数式编程:匿名函数在函数式编程中广泛应用,可以作为参数传递给其他函数,实现更加灵活的编程方式。
支持高阶函数:匿名函数可以作为高阶函数的参数,实现更加灵活的函数组合和调用方式。
简化代码结构:匿名函数可以直接嵌入到其他函数中,避免了定义多个小函数的复杂性,使代码结构更加清晰和简洁。
提高代码可读性:匿名函数通常用于处理简单的逻辑,将复杂的函数功能拆分成多个匿名函数,可以提高代码的可读性和可维护性。
匿名函数的语法
匿名函数的语法因编程语言而异,但通常比较简洁。以下是一些常见编程语言中匿名函数的示例:
python
lambda x, y: x + y
my_fun = lambda: print("景轩上课睡觉")
my_fun()
my_fun = lambda a, b: a if a > b else b
print(my_fun(10, 20))
my_fun = lambda name, msg: print(f"{name} {msg}")
my_fun(name=10, msg=20)
my_fun = lambda x, y: x + y
print(my_fun(10, 20))
def my_fun(m,n):
for i in range(m):
n()
my_fun(10, lambda :print("嘻嘻嘻"))
def my_fun(j, k, l):
j()
k()
l()
my_fun(lambda :print(7),lambda :print(10),lambda :print(11))
这个lambda函数可以赋值给变量或直接作为参数传递给其他函数,如map()、filter()等。
匿名函数的应用场景
匿名函数在多种编程场景中都有广泛的应用,包括但不限于:
回调函数:作为某些函数的参数,在特定事件发生时执行。
事件处理:在图形用户界面(GUI)编程中,处理用户输入事件(如点击、键盘输入等)。
数据处理:对数据进行简单的处理和转换,如过滤、映射、排序等。
高阶函数:作为参数传递给高阶函数,实现函数的组合和复用。
总之,匿名函数是一种非常灵活且强大的编程工具,它们可以在需要函数的地方直接定义和使用,从而简化代码结构、提高代码可读性和可维护性。