文件读写
文件读写是编程中常见的 IO 操作。
任务
现有一个 books.txt ,读取并检查是否包含中国四大名著,如有缺失,请补充缺失的名著并写入该文件中。
JavaScript 实现
import fs from 'fs';
const data = fs.readFileSync('books.txt', 'utf8');
const books = data.split('\n');
const classics = ['红楼梦', '西游记', '水浒传', '三国演义'];
const missingClassics = classics.filter(classic => !books.includes(classic));
if (missingClassics.length === 0) {
console.log('文件中已包含中国四大名著。');
return;
}
const missingClassicsText = missingClassics.join('\n');
fs.appendFileSync('books.txt', `\n${missingClassicsText}`, 'utf8');
console.log(`已补充缺失的名著到文件中: ${missingClassicsText}`);
Python 实现
# 读取books.txt文件内容
with open('books.txt', 'r', encoding='utf-8') as file:
books = file.read().splitlines()
# 检查是否包含中国四大名著
classics = ['红楼梦', '西游记', '水浒传', '三国演义']
missing_classics = [classic for classic in classics if classic not in books]
if len(missing_classics) == 0:
print('文件中已包含中国四大名著。')
else:
# 补充缺失的名著到文件中
with open('books.txt', 'a', encoding='utf-8') as file:
file.write('\n' + '\n'.join(missing_classics))
print(f'已补充缺失的名著到文件中: {", ".join(missing_classics)}')
代码解读
- Python 使用
open()函数打开文件,使用with语句确保文件被正确关闭。 - Python 使用
w、r、a指定文件的写、读、追加访问模式。
差异速览
| 特性 | JavaScript | Python |
|---|---|---|
| 读取文件 | fs.readFileSync(file, 'utf-8') | open(file, 'r', encoding='utf-8').read() |
| 写入文件 | fs.writeFileSync(file, data, 'utf-8') | open(file, 'w', encoding='utf-8').write() |
| 追加文件 | fs.appendFileSync(file, data, 'utf-8') | open(file, 'a', encoding='utf-8').write() |
相关资源
datetime 模块
Python 中的 datetime 模块提供了处理日期、时间和时间间隔的类和函数。
任务
小明的生日是 1992 年 1月 15 日,设计一个程序,计算他的年龄和距离下次生日的天数。
JavaScript 实现
// 获取当前日期
const currentDate = new Date();
// 设置小明的生日
const birthday = new Date(1992, 0, 15);
// 计算年龄
let age = currentDate.getFullYear() - birthday.getFullYear();
// 检查是否已经过了生日
if (currentDate.getMonth() < birthday.getMonth() || (currentDate.getMonth() === birthday.getMonth() && currentDate.getDate() < birthday.getDate())) {
age--;
}
// 计算距离下次生日的天数
const nextBirthday = new Date(currentDate.getFullYear(), birthday.getMonth(), birthday.getDate());
if (currentDate > nextBirthday) {
nextBirthday.setFullYear(nextBirthday.getFullYear() + 1);
}
const daysUntilNextBirthday = Math.ceil((nextBirthday - currentDate) / (1000 * 60 * 60 * 24));
// 输出结果
console.log("年龄: " + age);
console.log("距离下次生日的天数: " + daysUntilNextBirthday);
Python 实现
import datetime
# 获取当前日期
current_date = datetime.date.today()
# 设置小明的生日
birthday = datetime.date(1992, 1, 15)
# 计算年龄
age = current_date.year - birthday.year
if current_date.month < birthday.month or (current_date.month == birthday.month and current_date.day < birthday.day):
age -= 1
# 计算距离下次生日的天数
next_birthday = datetime.date(current_date.year, birthday.month, birthday.day)
if current_date > next_birthday:
next_birthday = datetime.date(current_date.year + 1, birthday.month, birthday.day)
days_until_next_birthday = (next_birthday - current_date).days
# 输出结果
print("年龄:", age)
print("距离下次生日的天数:", days_until_next_birthday)
代码解读
- 在 Python 中,从
datetime模块中导入date用于操作日期,而 JavaScript 使用Date。 - 在 Python 中,可以直接使用
+和-算术运算符对日期进行运算。
差异速览
| 特性 | JavaScript | Python |
|---|---|---|
| 创建日期时间对象 | new Date(1992, 0, 15) | datetime.datetime(1992, 1, 15) |
| 当前本地日期时间 | new Date() | datetime.datetime.now() |
| 当前 UTC 日期时间 | new Date().toUTCString() | datetime.datetime.utcnow() |
| 日期格式化 | moment(myDateTime).format(format) | my_datetime.strftime(format) |
| 获取年、月、日 | myDateTime.getFullYear() myDateTime.getMonth() + 1 myDateTime.getDate() | my_datetime.year my_datetime.month my_datetime.day |
| 获取时、分、秒 | myDateTime.getHours() myDateTime.getMinutes() myDateTime.getSeconds() | my_datetime.hourmy_datetime.minutemy_datetime.second |
| 添加时间间隔 | myDateTime.setSeconds(date.getSeconds() + secondsToAdd) | new_datetime = my_datetime + timedelta(seconds=secondsToAdd) |
| 减去时间间隔 | myDateTime.setSeconds(date.getSeconds() - secondsToSubtract) | new_datetime = my_datetime - timedelta(seconds=secondsToSubtract) |
| 比较日期 | dateTime1.getTime() - dateTime2.getTime() | datetime1 - datetime2 |
:::tip timedelta
如基本的日期时间运算无法满足需求,可以借助 timedelta,它是一个用于表示时间间隔的类。它可以用来执行日期和时间的加减操作,以及计算时间差。
from datetime import timedelta,datetime
current_datetime = datetime.now()
# 获取 2 天 3 小时 30 分钟 后的日期时间
new_datetime = current_datetime + timedelta(days=2, hours=3, minutes=30)
print(new_datetime)
:::
相关资源
os 模块
Python 中的 os 模块提供了用于操作文件和目录以及访问与系统相关的信息的函数。
任务
编写一个程序,列出给定目录中的所有文件和目录。该程序应打印每个项的名称,并指示它是文件还是目录。
JavaScript 实现
import fs from 'fs';
import path from 'path';
function listItems(directory) {
fs.readdir(directory, (err, items) => {
if (err) {
console.log(`读取目录时出错:${err}`);
return;
}
items.forEach((item) => {
const itemPath = path.join(directory, item);
fs.stat(itemPath, (err, stats) => {
if (err) {
console.log(`获取${item}的信息时出错:${err}`);
} else {
console.log(`${item}:${stats.isDirectory() ? '目录' : '文件'}`);
}
});
});
});
}
listItems('../');
Python 实现
import os
def list_items(directory):
items = os.listdir(directory)
for item in items:
item_path = os.path.join(directory, item)
if os.path.isdir(item_path):
print(f"{item}:目录")
else:
print(f"{item}:文件")
list_items('../')
差异速览
| 特性 | JavaScript | Python |
|---|---|---|
| 文件或目录是否存在 | fs.existsSync(path) | os.path.exists(path) |
| 创建目录 | fs.mkdir(path, [options], callback) | os.mkdir(path) |
| 列出目录 | fs.readdir(path, [options], callback) | os.listdir(path) |
相关资源
json 模块
Python 中的 json 模块提供了处理 JSON 数据的函数。
任务
设计一个程序,读取 database.json 中的 port属性的值,并将其修改为 5432,然后写回到该文件中。
JavaScript 实现
import fs from 'fs';
// 读取JSON文件
fs.readFile('database.json', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
try {
// 将JSON数据解析为JavaScript对象
const jsonData = JSON.parse(data);
// 修改port属性的值为5432
jsonData.port = 5432;
// 将JavaScript对象转换回JSON字符串
const updatedData = JSON.stringify(jsonData, null, 2);
// 将更新后的JSON字符串写回文件
fs.writeFile('database.json', updatedData, 'utf8', (err) => {
if (err) {
console.error(err);
return;
}
console.log('JSON文件已更新');
});
} catch (err) {
console.error('无法解析JSON文件:', err);
}
});
Python 实现
import json
# 读取JSON文件
with open('database.json', 'r') as file:
json_data = json.load(file)
# 修改port属性的值为5432
json_data['port'] = 5432
# 将更新后的JSON数据写回文件
with open('database.json', 'w') as file:
json.dump(json_data, file, indent=2)
print('JSON文件已更新')
代码解读
- Python 使用
json.dumps()将对象转换为 JSON 字符串,JavaScript 中的JSON.stringify()与之等效。 - Python 使用
json.loads()将 JSON 字符串转换为字典,JavaScript 中的JSON.parse()与之等效。
:::danger 中文编码问题
将 Python 对象转换为 JSON 字符串时,如果遇到中文乱码问题,可以使用 ensure_ascii=False 参数确保中文字符以原始的 Unicode 形式进行编码,而不是 ASCII 编码。例如:
import json
data = {"name": "张三", "age": 25}
json_str = json.dumps(data, ensure_ascii=False)
print(json_str)
:::
差异速览
| 特性 | JavaScript | Python |
|---|---|---|
| 解析 JSON 字符串 | JSON.parse(myStr) | json.loads(my_str) |
| 将对象转为 JSON 字符串 | JSON.stringify(myObj) | json.dumps(my_obj) |
| 读取 JSON 文件 | - | json.load(my_file) |
| 写入 JSON 文件 | - | json.dump(my_file) |
:::danger
Python 中使用 json.loads(my_str) 和 json.load(my_file) 会将得到一个 字典 或 列表(取决于 JSON 数据的结构)。对于字典以及嵌套字典而言,需要特别注意 Python 语法不支持使用点运算符(.)获取值,你需要需要使用 [] 获取值。
import json
my_dict = json.loads('{"name": "luckrnx09", "age": 18}')
print(my_dict.name) # Error: 'dict' object has no attribute 'name'
print(my_dict['name']) # luckrnx09
:::
相关资源
re 模块
正则表达式是编程语言中用于搜索、匹配和操作文本的强大工具,Python 中的 re 模块提供了对正则表达式的支持。
任务
编写一个程序,接受一个电子邮件地址列表,并使用正则表达式提取每个地址的用户名和域名。
JavaScript 实现
const emailAddresses = [
"john.doe@example1.com",
"jane.smith@example2.com",
"foo@bar.com",
];
const regex = /([^@]+)@(.+)/;
emailAddresses.forEach((email) => {
const [_, username, domain] = email.match(regex);
console.log(`Username: ${username}, Domain: ${domain}`);
});
Python实现:
import re
email_addresses = [
"john.doe@example1.com",
"jane.smith@example2.com",
"foo@bar.com",
]
regex = re.compile(r"([^@]+)@(.+)")
for email in email_addresses:
match = regex.match(email)
if match:
username, domain = match.groups()
print(f"Username: {username}, Domain: {domain}")
:::tip
Python 中的字符串前面添加 r,表示不对字符串字面量进行转义。
:::
代码解读
- 在 JavaScript 中,使用
/.../或new Regex(...)定义正则表达式,而在 Python 中,使用re.compile()函数创建正则表达式。
差异速览
| 特性 | JavaScript | Python |
|---|---|---|
| 创建正则表达式 | const myReg = /pattern/; 或 new Regex(pattern) | my_regex = re.compile(r'pattern') |
| 匹配正则表达式 | myReg.test(myStr) | my_regex.match(my_str) |
| 查找第一个匹配项 | myReg.exec(myStr) | my_regex.search(my_str) |
| 查找所有匹配项 | myStr.match(myReg) | my_regex.findall(my_str) |
| 替换匹配项 | myStr.replace(myReg, replacement) | my_regex.sub(replacement, my_str) |
| 使用正则表达式拆分字符串 | myStr.split(myReg) | my_regex.split(my_str) |
:::tip
除了使用 re.compile() 预先创建正则表达式外,你还可以直接使用 re 模块的 sub、'search' 等方法实现相同的功能,如:
import re
re.search(r'pattern', my_str)
re.split(r'pattern', my_str)
:::
相关资源
random 模块
Python 中的 random 模块提供了生成随机数的函数。
任务
生成一个包含随机大小写字母、数字的 32 位密码。
JavaScript 实现
function generatePassword() {
var length = 32;
var charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var password = "";
for (var i = 0; i < length; i++) {
var randomIndex = Math.floor(Math.random() * charset.length);
password += charset.charAt(randomIndex);
}
return password;
}
var password = generatePassword();
console.log(password);
Python 实现
import random
import string
def generate_password():
length = 32
charset = string.ascii_letters + string.digits
password = ''.join(random.choice(charset) for _ in range(length))
return password
password = generate_password()
print(password)
代码解读
- Python 中
string模块的ascii_letters包含了所有的小写和大写字母,digits包含了所有的数字。 - Python 使用
random.randint()函数生成给定最小值和最大值之间的随机整数,而在 JavaScript 中,我们使用自定义函数getRandomInt()利用Math.random()实现相同的功能。
差异速览
| 特性 | JavaScript | Python |
|---|---|---|
| 生成 0 到 1 之间的随机数 | Math.random() | random.random() |
| 在范围内生成随机整数 | Math.floor(Math.random() * (max - min + 1)) + min | random.randint(min_val, max_val) |
| 从列表中随机选择 1 个元素 | - | random.choice(sequence) |
| 对列表中的元素进行洗牌 | - | random.shuffle(sequence) |
| 在范围内生成随机浮点数 | - | random.uniform(min_val, max_val) |
| 设置随机种子 | - | random.seed(seed_val) |
相关资源
math 模块
Python 中的 math 模块提供了各种数学函数和常量。
任务
设计一个程序,通过输入半径来计算圆的面积。
JavaScript 实现
const radius = 5;
const area = Math.PI * Math.pow(radius, 2);
console.log(area);
Python 实现
import math
radius = 5
area = math.pi * math.pow(radius, 2)
print(area)
差异速览
| 特性 | JavaScript | Python |
|---|---|---|
| 绝对值 | Math.abs(x) | abs(x) |
| 四舍五入到最近的整数 | Math.round(x) | round(x) |
| 向上取整(不小于x的最小整数) | Math.ceil(x) | math.ceil(x) |
| 向下取整(不大于x的最大整数) | Math.floor(x) | math.floor(x) |
| 指数运算 | Math.pow(x, y) | pow(x, y) |
| 平方根 | Math.sqrt(x) | math.sqrt(x) |
| 三角函数 | Math.sin(x)、Math.cos(x)、Math.tan(x)、Math.asin(x)、Math.acos(x)、Math.atan(x) | math.sin(x)、math.cos(x)、math.tan(x)、math.asin(x)、math.acos(x)、math.atan(x) |
| 将角度转换为弧度 | - | math.radians(x) |
| 将弧度转换为角度 | - | math.degrees(x) |
相关资源
本书的内容完全免费,开源地址:github.com/luckrnx09/p…