跳到主要内容
Python 极简教程:Java 开发者视角入门实战 | 极客日志
Python AI java
Python 极简教程:Java 开发者视角入门实战 综述由AI生成 从 Java 开发者视角出发,全面对比了 Java 与 Python 在环境搭建、语法基础、数据类型、控制流、数据结构、函数、面向对象、异常处理、模块、文件操作、数据库及并发编程等方面的核心差异。文章通过大量代码示例展示了两种语言在实现相同功能时的写法区别,帮助 Java 开发者快速掌握 Python 核心语法与实战技巧,并提供了简易 RESTful API 服务的完整案例。适合希望拓展技术栈、利用 Python 进行数据分析或快速开发的 Java 工程师阅读。
PhpPioneer 发布于 2026/3/30 更新于 2026/5/23 25 浏览引言:为什么 Java 开发者需要学 Python?
作为一名 Java 开发者,你可能已经习惯了强类型、编译型、面向对象的编程范式。Java 以其严谨性、健壮性和广泛的企业级应用而闻名,但在某些场景下,它的 "重量级" 特性反而成为了束缚。
Python,作为一门解释型、动态类型的语言,正在人工智能、数据分析、自动化脚本、快速原型开发等领域大放异彩。对于 Java 开发者来说,掌握 Python 不仅能拓宽技术视野,更能在合适的场景下选择更高效的工具。
本教程将从 Java 开发者的视角,通过对比两种语言的异同,带你快速掌握 Python 的核心语法和实战技巧。我们不会面面俱到,但会直击要点,让你用最短的时间具备 Python 开发能力。
1. 环境搭建:从 JDK 到 Python 解释器
1.1 Java 与 Python 环境对比
在 Java 世界,我们需要安装 JDK(Java Development Kit),配置环境变量,通常还会使用 Maven 或 Gradle 进行项目管理。
Python 的环境搭建则简单得多:
安装 Python 解释器(相当于 JRE)
可选安装 pip(Python 包管理工具,相当于 Maven)
可选安装虚拟环境(用于隔离不同项目的依赖)
1.2 Python 环境安装步骤
访问 Python 官网下载最新稳定版(推荐 3.11+)
安装时勾选 "Add Python to PATH"(相当于 Java 的环境变量配置)
验证安装:
python --version
pip --version
1.3 开发工具选择
Java 开发者常用的 IDE 如 IntelliJ IDEA、Eclipse 都有优秀的 Python 插件支持。此外,PyCharm(与 IDEA 同属 JetBrains)是 Python 专用 IDE,VS Code 也有出色的 Python 支持。
2. 语法基础:从 HelloWorld 看两种语言的差异
2.1 第一个程序:Hello World
Java 版本:
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class HelloWorld {
public static void main (String[] args) {
log.info("Hello, World!" );
}
}
Python 版本:
print ("Hello, World!" )
2.2 核心差异解析
结构差异 :
Java 需要类(class)作为容器,包含 main 方法作为入口
Python 可以直接写执行语句,无需类和方法包裹
语法元素 :
Java 使用分号 (;) 结束语句,Python 依靠换行
Java 使用大括号 ({}) 划分代码块,Python 使用缩进
Java 需要显式导入,Python 部分功能需要导入,基础功能直接可用
日志输出 :
Java 中推荐使用 SLF4J 等日志框架
Python 内置 print 函数用于简单输出,复杂日志可使用 logging 模块
3. 数据类型:动态类型与静态类型的碰撞
3.1 类型系统对比
变量声明时必须指定类型
编译期检查类型正确性
类型转换需要显式进行
变量无需声明类型,赋值时自动确定
运行期检查类型
类型转换通常需要显式进行
3.2 基本数据类型对比 Java 类型 Python 类型 说明 int int 整数,Python3 中 int 可表示任意大小整数 long int Python 中没有 long,int 可自动扩展 float float 单精度浮点数 double float Python 中 float 实际是双精度 boolean bool 布尔值,Python 中是 True/False char str Python 中没有 char,用长度为 1 的字符串表示 String str 字符串,Python 中用单引号或双引号
3.3 变量定义与使用 import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
@Slf4j
public class VariableDemo {
public static void main (String[] args) {
int age = 30 ;
double height = 1.85 ;
boolean isStudent = false ;
String name = "Alice" ;
log.info("姓名:{}" , name);
log.info("年龄:{}" , age);
String ageStr = String.valueOf(age);
if (StringUtils.hasText(ageStr)) {
log.info("年龄字符串:{}" , ageStr);
}
}
}
age = 30
height = 1.85
is_student = False
name = "Alice"
print (f"姓名:{name} " )
print (f"年龄:{age} " )
age_str = str (age)
if age_str:
print (f"年龄字符串:{age_str} " )
3.4 字符串操作 import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
@Slf4j
public class StringDemo {
public static void main (String[] args) {
String str1 = "Hello" ;
String str2 = "World" ;
String greeting = str1 + ", " + str2 + "!" ;
log.info(greeting);
log.info("长度:{}" , greeting.length());
String substr = greeting.substring(0 , 5 );
log.info("子串:{}" , substr);
String[] parts = "a,b,c,d" .split("," );
log.info("分割后第一个元素:{}" , parts[0 ]);
String formatted = String.format("Name: %s, Age: %d" , "Bob" , 25 );
log.info(formatted);
}
}
str1 = "Hello"
str2 = "World"
greeting = f"{str1} , {str2} !"
print (greeting)
print (f"长度:{len (greeting)} " )
substr = greeting[0 :5 ]
print (f"子串:{substr} " )
parts = "a,b,c,d" .split("," )
print (f"分割后第一个元素:{parts[0 ]} " )
formatted = f"Name: {'Bob' } , Age: {25 } "
print (formatted)
4. 控制流:程序的执行路径
4.1 条件语句 import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ConditionDemo {
public static void main (String[] args) {
int score = 85 ;
if (score >= 90 ) {
log.info("优秀" );
} else if (score >= 80 ) {
log.info("良好" );
} else if (score >= 60 ) {
log.info("及格" );
} else {
log.info("不及格" );
}
String result = score >= 60 ? "通过" : "未通过" ;
log.info(result);
}
}
score = 85
if score >= 90 :
print ("优秀" )
elif score >= 80 :
print ("良好" )
elif score >= 60 :
print ("及格" )
else :
print ("不及格" )
result = "通过" if score >= 60 else "未通过"
print (result)
4.2 循环语句 import lombok.extern.slf4j.Slf4j;
import com.google.common.collect.Lists;
import java.util.List;
@Slf4j
public class LoopDemo {
public static void main (String[] args) {
List<String> fruits = Lists.newArrayList("苹果" , "香蕉" , "橙子" );
for (String fruit : fruits) {
log.info(fruit);
}
for (int i = 0 ; i < 5 ; i++) {
log.info("计数:{}" , i);
}
int count = 0 ;
while (count < 3 ) {
log.info("While 计数:{}" , count);
count++;
}
}
}
fruits = ["苹果" , "香蕉" , "橙子" ]
for fruit in fruits:
print (fruit)
for i in range (5 ):
print (f"计数:{i} " )
count = 0
while count < 3 :
print (f"While 计数:{count} " )
count += 1
4.3 循环控制 import lombok.extern.slf4j.Slf4j;
@Slf4j
public class LoopControlDemo {
public static void main (String[] args) {
for (int i = 0 ; i < 10 ; i++) {
if (i == 5 ) {
break ;
}
log.info("Break 示例:{}" , i);
}
for (int i = 0 ; i < 10 ; i++) {
if (i % 2 == 0 ) {
continue ;
}
log.info("Continue 示例:{}" , i);
}
}
}
for i in range (10 ):
if i == 5 :
break
print (f"Break 示例:{i} " )
for i in range (10 ):
if i % 2 == 0 :
continue
print (f"Continue 示例:{i} " )
5. 数据结构:从 Collection 到 Python 内置结构
5.1 数据结构对比概览
5.2 列表(List) Java 的 ArrayList 对应 Python 的 list:
import lombok.extern.slf4j.Slf4j;
import com.google.common.collect.Lists;
import org.springframework.util.CollectionUtils;
import java.util.List;
@Slf4j
public class ListDemo {
public static void main (String[] args) {
List<String> fruits = Lists.newArrayList("苹果" , "香蕉" , "橙子" );
fruits.add("葡萄" );
String firstFruit = fruits.get(0 );
log.info("第一个水果:{}" , firstFruit);
fruits.set(1 , "草莓" );
fruits.remove(2 );
boolean hasApple = fruits.contains("苹果" );
log.info("是否包含苹果:{}" , hasApple);
log.info("列表大小:{}" , fruits.size());
if (!CollectionUtils.isEmpty(fruits)) {
for (String fruit : fruits) {
log.info(fruit);
}
}
}
}
fruits = ["苹果" , "香蕉" , "橙子" ]
fruits.append("葡萄" )
first_fruit = fruits[0 ]
print (f"第一个水果:{first_fruit} " )
fruits[1 ] = "草莓"
del fruits[2 ]
has_apple = "苹果" in fruits
print (f"是否包含苹果:{has_apple} " )
print (f"列表大小:{len (fruits)} " )
if fruits:
for fruit in fruits:
print (fruit)
5.3 集合(Set) Java 的 HashSet 对应 Python 的 set:
import lombok.extern.slf4j.Slf4j;
import com.google.common.collect.Sets;
import org.springframework.util.CollectionUtils;
import java.util.Set;
@Slf4j
public class SetDemo {
public static void main (String[] args) {
Set<String> fruits = Sets.newHashSet("苹果" , "香蕉" , "橙子" , "苹果" );
fruits.add("葡萄" );
boolean hasApple = fruits.contains("苹果" );
log.info("是否包含苹果:{}" , hasApple);
log.info("集合大小:{}" , fruits.size());
fruits.remove("香蕉" );
if (!CollectionUtils.isEmpty(fruits)) {
for (String fruit : fruits) {
log.info(fruit);
}
}
Set<String> set1 = Sets.newHashSet("a" , "b" , "c" );
Set<String> set2 = Sets.newHashSet("b" , "c" , "d" );
Set<String> intersection = Sets.intersection(set1, set2);
log.info("交集:{}" , intersection);
Set<String> union = Sets.union(set1, set2);
log.info("并集:{}" , union);
}
}
fruits = {"苹果" , "香蕉" , "橙子" , "苹果" }
fruits.add("葡萄" )
has_apple = "苹果" in fruits
print (f"是否包含苹果:{has_apple} " )
print (f"集合大小:{len (fruits)} " )
fruits.remove("香蕉" )
if fruits:
for fruit in fruits:
print (fruit)
set1 = {"a" , "b" , "c" }
set2 = {"b" , "c" , "d" }
intersection = set1 & set2
print (f"交集:{intersection} " )
union = set1 | set2
print (f"并集:{union} " )
5.4 字典(Dictionary) Java 的 HashMap 对应 Python 的 dict:
import lombok.extern.slf4j.Slf4j;
import com.google.common.collect.Maps;
import org.springframework.util.CollectionUtils;
import java.util.Map;
@Slf4j
public class MapDemo {
public static void main (String[] args) {
Map<String, Integer> fruitPrices = Maps.newHashMap();
fruitPrices.put("苹果" , 10 );
fruitPrices.put("香蕉" , 5 );
fruitPrices.put("橙子" , 8 );
int applePrice = fruitPrices.get("苹果" );
log.info("苹果价格:{}" , applePrice);
boolean hasBanana = fruitPrices.containsKey("香蕉" );
log.info("是否有香蕉:{}" , hasBanana);
log.info("映射大小:{}" , fruitPrices.size());
fruitPrices.remove("香蕉" );
if (!CollectionUtils.isEmpty(fruitPrices)) {
for (Map.Entry<String, Integer> entry : fruitPrices.entrySet()) {
log.info("{}: {}" , entry.getKey(), entry.getValue());
}
}
}
}
fruit_prices = {}
fruit_prices["苹果" ] = 10
fruit_prices["香蕉" ] = 5
fruit_prices["橙子" ] = 8
apple_price = fruit_prices["苹果" ]
print (f"苹果价格:{apple_price} " )
has_banana = "香蕉" in fruit_prices
print (f"是否有香蕉:{has_banana} " )
print (f"字典大小:{len (fruit_prices)} " )
del fruit_prices["香蕉" ]
if fruit_prices:
for fruit, price in fruit_prices.items():
print (f"{fruit} : {price} " )
5.5 元组(Tuple)
point = (10 , 20 )
colors = ("红" , "绿" , "蓝" )
x = point[0 ]
print (f"X 坐标:{x} " )
print (f"颜色数量:{len (colors)} " )
for color in colors:
print (color)
a, b, c = colors
print (f"解包后:a={a} , b={b} , c={c} " )
single_element = (5 ,)
print (f"单元素元组:{single_element} " )
6. 函数:从方法到函数
6.1 函数定义与调用 import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MethodDemo {
public static int add (int a, int b) {
return a + b;
}
public static void greet (String name) {
log.info("Hello, {}!" , name);
}
public static void main (String[] args) {
int sum = add(3 , 5 );
log.info("3 + 5 = {}" , sum);
greet("Alice" );
}
}
def add (a, b ):
""" 计算两个数的和
@param a: 第一个数
@param b: 第二个数
@return: 两个数的和
"""
return a + b
def greet (name ):
""" 打印问候语
@param name: 姓名
"""
print (f"Hello, {name} !" )
sum_result = add(3 , 5 )
print (f"3 + 5 = {sum_result} " )
greet("Alice" )
6.2 函数参数 Python 支持多种灵活的参数形式,这是与 Java 方法参数的主要区别:
def power (base, exponent ):
"""计算 base 的 exponent 次方"""
result = 1
for _ in range (exponent):
result *= base
return result
print (power(2 , 3 ))
def greet (name, greeting="Hello" ):
"""带默认值的问候函数"""
print (f"{greeting} , {name} !" )
greet("Alice" )
greet("Bob" , "Hi" )
def describe_person (name, age, city ):
"""描述一个人的信息"""
print (f"{name} is {age} years old and lives in {city} " )
describe_person(age=30 , name="Charlie" , city="New York" )
def sum_numbers (*numbers ):
"""计算任意数量数字的和"""
total = 0
for num in numbers:
total += num
return total
print (sum_numbers(1 , 2 , 3 , 4 ))
def print_info (**info ):
"""打印任意关键字参数"""
for key, value in info.items():
print (f"{key} : {value} " )
print_info(name="David" , age=25 , occupation="Engineer" )
6.3 函数返回值 Python 函数可以返回多个值,这在 Java 中需要通过自定义对象或数组实现:
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MultipleReturnDemo {
@Data
public static class IntResult {
private int sum;
private int product;
public IntResult (int sum, int product) {
this .sum = sum;
this .product = product;
}
}
public static IntResult calculate (int a, int b) {
int sum = a + b;
int product = a * b;
return new IntResult (sum, product);
}
public static void main (String[] args) {
IntResult result = calculate(3 , 4 );
log.info("和:{}" , result.getSum());
log.info("积:{}" , result.getProduct());
}
}
def calculate (a, b ):
""" 计算两个数的和与积
@param a: 第一个数
@param b: 第二个数
@return: 包含和与积的元组
"""
sum_result = a + b
product_result = a * b
return sum_result, product_result
sum_val, product_val = calculate(3 , 4 )
print (f"和:{sum_val} " )
print (f"积:{product_val} " )
result = calculate(3 , 4 )
print (f"结果元组:{result} " )
7. 面向对象编程:从类到对象
7.1 类与对象基础 import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class OOPBasics {
@Data
public static class Student {
private String name;
private int age;
private String major;
public Student (String name, int age, String major) {
this .name = name;
this .age = age;
this .major = major;
}
public void introduce () {
log.info("大家好,我叫{},今年{}岁,专业是{}" , name, age, major);
}
public void study (String course) {
log.info("{}正在学习{}" , name, course);
}
}
public static void main (String[] args) {
Student student = new Student ("张三" , 20 , "计算机科学" );
student.introduce();
student.study("Python 编程" );
log.info("学生姓名:{}" , student.getName());
student.setAge(21 );
log.info("修改后的年龄:{}" , student.getAge());
}
}
class Student :
"""学生类"""
def __init__ (self, name, age, major ):
""" 构造方法
@param name: 姓名
@param age: 年龄
@param major: 专业
"""
self .name = name
self .age = age
self .major = major
def introduce (self ):
"""学生自我介绍"""
print (f"大家好,我叫{self.name} ,今年{self.age} 岁,专业是{self.major} " )
def study (self, course ):
""" 学生学习
@param course: 课程名称
"""
print (f"{self.name} 正在学习{course} " )
student = Student("张三" , 20 , "计算机科学" )
student.introduce()
student.study("Python 编程" )
print (f"学生姓名:{student.name} " )
student.age = 21
print (f"修改后的年龄:{student.age} " )
7.2 继承 import lombok.extern.slf4j.Slf4j;
@Slf4j
public class InheritanceDemo {
public static class Animal {
protected String name;
public Animal (String name) {
this .name = name;
}
public void eat () {
log.info("{}在吃东西" , name);
}
public void sleep () {
log.info("{}在睡觉" , name);
}
}
public static class Dog extends Animal {
public Dog (String name) {
super (name);
}
@Override
public void eat () {
log.info("{}在吃骨头" , name);
}
public void bark () {
log.info("{}在汪汪叫" , name);
}
}
public static class Cat extends Animal {
public Cat (String name) {
super (name);
}
@Override
public void eat () {
log.info("{}在吃鱼" , name);
}
public void meow () {
log.info("{}在喵喵叫" , name);
}
}
public static void main (String[] args) {
Animal dog = new Dog ("旺财" );
Animal cat = new Cat ("咪咪" );
dog.eat();
dog.sleep();
((Dog) dog).bark();
cat.eat();
cat.sleep();
((Cat) cat).meow();
}
}
class Animal :
"""动物类(父类)"""
def __init__ (self, name ):
self .name = name
def eat (self ):
print (f"{self.name} 在吃东西" )
def sleep (self ):
print (f"{self.name} 在睡觉" )
class Dog (Animal ):
"""狗类(子类)"""
def eat (self ):
"""重写父类方法"""
print (f"{self.name} 在吃骨头" )
def bark (self ):
"""子类特有方法"""
print (f"{self.name} 在汪汪叫" )
class Cat (Animal ):
"""猫类(子类)"""
def eat (self ):
"""重写父类方法"""
print (f"{self.name} 在吃鱼" )
def meow (self ):
"""子类特有方法"""
print (f"{self.name} 在喵喵叫" )
dog = Dog("旺财" )
cat = Cat("咪咪" )
dog.eat()
dog.sleep()
dog.bark()
cat.eat()
cat.sleep()
cat.meow()
7.3 封装 import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class EncapsulationDemo {
@Getter
public static class BankAccount {
private String accountNumber;
@Setter
private String ownerName;
private double balance;
public BankAccount (String accountNumber, String ownerName, double initialBalance) {
this .accountNumber = accountNumber;
this .ownerName = ownerName;
this .balance = initialBalance > 0 ? initialBalance : 0 ;
}
public void deposit (double amount) {
if (amount > 0 ) {
balance += amount;
log.info("存款成功,金额:{}" , amount);
} else {
log.error("存款金额必须为正数" );
}
}
public boolean withdraw (double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
log.info("取款成功,金额:{}" , amount);
return true ;
}
log.error("取款失败,金额无效或余额不足" );
return false ;
}
public double getBalance () {
log.info("查询余额" );
return balance;
}
}
public static void main (String[] args) {
BankAccount account = new BankAccount ("123456789" , "张三" , 1000 );
log.info("账号:{}" , account.getAccountNumber());
log.info("户主:{}" , account.getOwnerName());
log.info("余额:{}" , account.getBalance());
account.deposit(500 );
log.info("存款后余额:{}" , account.getBalance());
boolean withdrawSuccess = account.withdraw(300 );
if (withdrawSuccess) {
log.info("取款后余额:{}" , account.getBalance());
}
account.setOwnerName("李四" );
log.info("修改后户主:{}" , account.getOwnerName());
}
}
class BankAccount :
"""银行账户类"""
def __init__ (self, account_number, owner_name, initial_balance ):
self ._account_number = account_number
self ._owner_name = owner_name
self .__balance = initial_balance if initial_balance > 0 else 0
@property
def account_number (self ):
"""账号的 getter 方法"""
return self ._account_number
@property
def owner_name (self ):
"""户主姓名的 getter 方法"""
return self ._owner_name
@owner_name.setter
def owner_name (self, new_name ):
"""户主姓名的 setter 方法"""
self ._owner_name = new_name
def deposit (self, amount ):
""" 存款
@param amount: 存款金额
"""
if amount > 0 :
self .__balance += amount
print (f"存款成功,金额:{amount} " )
else :
print ("存款金额必须为正数" )
def withdraw (self, amount ):
""" 取款
@param amount: 取款金额
@return: 是否取款成功
"""
if amount > 0 and amount <= self .__balance:
self .__balance -= amount
print (f"取款成功,金额:{amount} " )
return True
print ("取款失败,金额无效或余额不足" )
return False
def get_balance (self ):
"""获取余额"""
print ("查询余额" )
return self .__balance
account = BankAccount("123456789" , "张三" , 1000 )
print (f"账号:{account.account_number} " )
print (f"户主:{account.owner_name} " )
print (f"余额:{account.get_balance()} " )
account.deposit(500 )
print (f"存款后余额:{account.get_balance()} " )
withdraw_success = account.withdraw(300 )
if withdraw_success:
print (f"取款后余额:{account.get_balance()} " )
account.__balance = 1000000
print (f"尝试修改后余额:{account.get_balance()} " )
account.owner_name = "李四"
print (f"修改后户主:{account.owner_name} " )
8. 异常处理:从 try-catch 到 Python 的异常机制
8.1 异常处理基础 import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ExceptionHandlingDemo {
public static double divide (double a, double b) {
if (b == 0 ) {
throw new ArithmeticException ("除数不能为 0" );
}
return a / b;
}
public static void main (String[] args) {
try {
double result = divide(10 , 2 );
log.info("10 / 2 = {}" , result);
result = divide(10 , 0 );
log.info("10 / 0 = {}" , result);
} catch (ArithmeticException e) {
log.error("发生算术异常:{}" , e.getMessage());
} finally {
log.info("运算结束" );
}
String[] fruits = {"苹果" , "香蕉" , "橙子" };
try {
int index = Integer.parseInt("abc" );
log.info(fruits[index]);
} catch (NumberFormatException e) {
log.error("数字格式异常:无法将字符串转换为整数" );
} catch (ArrayIndexOutOfBoundsException e) {
log.error("数组索引越界异常:索引超出数组范围" );
} catch (Exception e) {
log.error("发生未知异常:{}" , e.getMessage());
}
}
}
def divide (a, b ):
""" 除法运算
@param a: 被除数
@param b: 除数
@return: 商
@raise ArithmeticError: 当除数为 0 时抛出
"""
if b == 0 :
raise ArithmeticError("除数不能为 0" )
return a / b
try :
result = divide(10 , 2 )
print (f"10 / 2 = {result} " )
result = divide(10 , 0 )
print (f"10 / 0 = {result} " )
except ArithmeticError as e:
print (f"发生算术异常:{str (e)} " )
finally :
print ("运算结束" )
fruits = ["苹果" , "香蕉" , "橙子" ]
try :
index = int ("abc" )
print (fruits[index])
except ValueError:
print ("值错误:无法将字符串转换为整数" )
except IndexError:
print ("索引错误:索引超出数组范围" )
except Exception as e:
print (f"发生未知异常:{str (e)} " )
8.2 自定义异常 import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CustomExceptionDemo {
public static class UserNotFoundException extends Exception {
public UserNotFoundException (String message) {
super (message);
}
}
public static class PermissionDeniedException extends Exception {
public PermissionDeniedException (String message) {
super (message);
}
}
public static void checkUserExists (String userId) throws UserNotFoundException {
if ("000" .equals(userId)) {
throw new UserNotFoundException ("用户不存在:" + userId);
}
}
public static void checkPermission (String userId) throws PermissionDeniedException {
if ("123" .equals(userId)) {
throw new PermissionDeniedException ("用户权限不足:" + userId);
}
}
public static void main (String[] args) {
String userId = "123" ;
try {
checkUserExists(userId);
checkPermission(userId);
log.info("用户 {} 验证通过" , userId);
} catch (UserNotFoundException | PermissionDeniedException e) {
log.error("验证失败:{}" , e.getMessage());
} catch (Exception e) {
log.error("发生未知错误:{}" , e.getMessage());
}
}
}
class UserNotFoundException (Exception ):
"""自定义异常:用户不存在异常"""
pass
class PermissionDeniedException (Exception ):
"""自定义异常:权限不足异常"""
pass
def check_user_exists (user_id ):
""" 检查用户是否存在
@param user_id: 用户 ID
@raise UserNotFoundException: 当用户不存在时抛出
"""
if user_id == "000" :
raise UserNotFoundException(f"用户不存在:{user_id} " )
def check_permission (user_id ):
""" 检查用户权限
@param user_id: 用户 ID
@raise PermissionDeniedException: 当权限不足时抛出
"""
if user_id == "123" :
raise PermissionDeniedException(f"用户权限不足:{user_id} " )
user_id = "123"
try :
check_user_exists(user_id)
check_permission(user_id)
print (f"用户 {user_id} 验证通过" )
except (UserNotFoundException, PermissionDeniedException) as e:
print (f"验证失败:{str (e)} " )
except Exception as e:
print (f"发生未知错误:{str (e)} " )
9. 模块与包:从 Jar 到 Python 模块
9.1 模块的导入与使用 Java 中我们通过 import 语句导入类,Python 中则通过 import 语句导入模块:
Python 模块示例(创建一个名为 math_utils.py 的文件):
PI = 3.1415926535
def add (a, b ):
"""加法运算"""
return a + b
def subtract (a, b ):
"""减法运算"""
return a - b
def multiply (a, b ):
"""乘法运算"""
return a * b
def divide (a, b ):
"""除法运算"""
if b == 0 :
raise ValueError("除数不能为 0" )
return a / b
def circle_area (radius ):
"""计算圆的面积"""
return PI * radius * radius
import math_utils
print (f"PI 的值:{math_utils.PI} " )
print (f"3 + 5 = {math_utils.add(3 , 5 )} " )
print (f"半径为 2 的圆面积:{math_utils.circle_area(2 )} " )
import math_utils as mu
print (f"10 - 4 = {mu.subtract(10 , 4 )} " )
from math_utils import multiply, PI
print (f"6 * 7 = {multiply(6 , 7 )} " )
print (f"再次打印 PI: {PI} " )
from math_utils import *
print (f"10 / 2 = {divide(10 , 2 )} " )
9.2 包的结构与使用 Python 的包类似于 Java 的包,是模块的集合。一个包含 __init__.py 文件的目录就是一个 Python 包。
my_package/
├── __init__ .py
├── math_ utils.py
└── string_utils.py
__init__.py 文件可以为空,也可以包含包的初始化代码:
__all__ = ['math_utils' , 'string_utils' ]
print ("my_package 包被导入了" )
def to_upper (s ):
"""转换为大写"""
return s.upper()
def to_lower (s ):
"""转换为小写"""
return s.lower()
def reverse (s ):
"""反转字符串"""
return s[::-1 ]
from my_package import math_utils, string_utils
print (f"5 * 8 = {math_utils.multiply(5 , 8 )} " )
print (f"反转字符串:{string_utils.reverse('hello' )} " )
from my_package import math_utils as mu
print (f"圆面积:{mu.circle_area(3 )} " )
from my_package.string_utils import to_upper
print (f"转换为大写:{to_upper('hello world' )} " )
from my_package import *
print (f"3.14 / 2 = {math_utils.divide(3.14 , 2 )} " )
print (f"转换为小写:{string_utils.to_lower('HELLO' )} " )
9.3 常用标准库 Python 拥有丰富的标准库,相当于 Java 的 JDK 类库:
import time
import datetime
print (f"当前时间戳:{time.time()} " )
print (f"本地时间:{time.localtime()} " )
print (f"格式化时间:{time.strftime('%Y-%m-%d %H:%M:%S' )} " )
today = datetime.date.today()
print (f"今天日期:{today} " )
tomorrow = today + datetime.timedelta(days=1 )
print (f"明天日期:{tomorrow} " )
import math
import random
print (f"圆周率:{math.pi} " )
print (f"正弦值:{math.sin(math.pi / 2 )} " )
print (f"平方根:{math.sqrt(16 )} " )
print (f"随机整数:{random.randint(1 , 100 )} " )
print (f"随机选择:{random.choice(['红' , '绿' , '蓝' ])} " )
import os
import shutil
print (f"当前目录:{os.getcwd()} " )
print (f"目录内容:{os.listdir('.' )} " )
import gzip
import json
data = {"name" : "张三" , "age" : 30 , "hobbies" : ["读书" , "运动" ]}
json_str = json.dumps(data, ensure_ascii=False )
print (f"JSON 字符串:{json_str} " )
parsed_data = json.loads(json_str)
print (f"解析后的姓名:{parsed_data['name' ]} " )
10. 文件操作:从 InputStream 到 Python 文件处理
10.1 文件读写基础 import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
@Slf4j
public class FileOperationDemo {
public static void main (String[] args) {
String filename = "example.txt" ;
try (BufferedWriter writer = new BufferedWriter (
new OutputStreamWriter (
new FileOutputStream (filename), StandardCharsets.UTF_8))) {
writer.write("Hello, World!" );
writer.newLine();
writer.write("这是一个文件写入示例。" );
log.info("文件写入成功" );
} catch (IOException e) {
log.error("文件写入失败:{}" , e.getMessage());
}
try (BufferedReader reader = new BufferedReader (
new InputStreamReader (
new FileInputStream (filename), StandardCharsets.UTF_8))) {
String line;
log.info("文件内容:" );
while ((line = reader.readLine()) != null ) {
log.info(line);
}
} catch (IOException e) {
log.error("文件读取失败:{}" , e.getMessage());
}
try {
List<String> lines = Files.readAllLines(Paths.get(filename), StandardCharsets.UTF_8);
log.info("使用 NIO 读取文件内容:" );
for (String line : lines) {
log.info(line);
}
} catch (IOException e) {
log.error("NIO 文件读取失败:{}" , e.getMessage());
}
}
}
filename = "example.txt"
try :
with open (filename, "w" , encoding="utf-8" ) as writer:
writer.write("Hello, World!\n" )
writer.write("这是一个文件写入示例。" )
print ("文件写入成功" )
except IOError as e:
print (f"文件写入失败:{str (e)} " )
try :
with open (filename, "r" , encoding="utf-8" ) as reader:
print ("文件内容:" )
for line in reader:
print (line.strip())
except IOError as e:
print (f"文件读取失败:{str (e)} " )
try :
with open (filename, "r" , encoding="utf-8" ) as reader:
content = reader.read()
print ("所有文件内容:" )
print (content)
except IOError as e:
print (f"文件读取失败:{str (e)} " )
try :
with open (filename, "r" , encoding="utf-8" ) as reader:
lines = reader.readlines()
print ("所有行:" )
for line in lines:
print (line.strip())
except IOError as e:
print (f"文件读取失败:{str (e)} " )
10.2 二进制文件操作 import lombok.extern.slf4j.Slf4j;
import java.io.*;
@Slf4j
public class BinaryFileDemo {
public static void main (String[] args) {
String sourceFile = "source.bin" ;
String destFile = "dest.bin" ;
try (DataOutputStream dos = new DataOutputStream (
new FileOutputStream (sourceFile))) {
dos.writeInt(42 );
dos.writeDouble(3.14159 );
dos.writeUTF("Hello, Binary World!" );
log.info("二进制文件写入成功" );
} catch (IOException e) {
log.error("二进制文件写入失败:{}" , e.getMessage());
}
try (DataInputStream dis = new DataInputStream (
new FileInputStream (sourceFile))) {
int intValue = dis.readInt();
double doubleValue = dis.readDouble();
String stringValue = dis.readUTF();
log.info("读取二进制数据:" );
log.info("整数:{}" , intValue);
log.info("浮点数:{}" , doubleValue);
log.info("字符串:{}" , stringValue);
} catch (IOException e) {
log.error("二进制文件读取失败:{}" , e.getMessage());
}
try (InputStream in = new FileInputStream (sourceFile); OutputStream out = new FileOutputStream (destFile)) {
byte [] buffer = new byte [1024 ];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1 ) {
out.write(buffer, 0 , bytesRead);
}
log.info("二进制文件复制成功" );
} catch (IOException e) {
log.error("二进制文件复制失败:{}" , e.getMessage());
}
}
}
source_file = "source.bin"
dest_file = "dest.bin"
try :
with open (source_file, "wb" ) as f:
f.write((42 ).to_bytes(4 , byteorder='big' ))
import struct
f.write(struct.pack('d' , 3.14159 ))
f.write("Hello, Binary World!" .encode('utf-8' ))
print ("二进制文件写入成功" )
except IOError as e:
print (f"二进制文件写入失败:{str (e)} " )
try :
with open (source_file, "rb" ) as f:
int_bytes = f.read(4 )
int_value = int .from_bytes(int_bytes, byteorder='big' )
double_bytes = f.read(8 )
double_value = struct.unpack('d' , double_bytes)[0 ]
str_bytes = f.read()
str_value = str_bytes.decode('utf-8' )
print ("读取二进制数据:" )
print (f"整数:{int_value} " )
print (f"浮点数:{double_value} " )
print (f"字符串:{str_value} " )
except IOError as e:
print (f"文件读取失败:{str (e)} " )
try :
with open (source_file, "rb" ) as in_file, open (dest_file, "wb" ) as out_file:
while True :
buffer = in_file.read(1024 )
if not buffer:
break
out_file.write(buffer)
print ("二进制文件复制成功" )
except IOError as e:
print (f"二进制文件复制失败:{str (e)} " )
11. 数据库操作:从 JDBC 到 Python DB API
11.1 MySQL 数据库操作 <dependencies >
<dependency >
<groupId > org.projectlombok</groupId >
<artifactId > lombok</artifactId >
<version > 1.18.30</version >
<scope > provided</scope >
</dependency >
<dependency >
<groupId > org.slf4j</groupId >
<artifactId > slf4j-api</artifactId >
<version > 2.0.9</version >
</dependency >
<dependency >
<groupId > org.slf4j</groupId >
<artifactId > slf4j-simple</artifactId >
<version > 2.0.9</version >
</dependency >
<dependency >
<groupId > com.mysql</groupId >
<artifactId > mysql-connector-j</artifactId >
<version > 8.1.0</version >
</dependency >
<dependency >
<groupId > com.baomidou</groupId >
<artifactId > mybatis-plus-boot-starter</artifactId >
<version > 3.5.3.1</version >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter</artifactId >
<version > 3.1.3</version >
</dependency >
</dependencies >
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDateTime;
@Data
@TableName("user")
@Schema(description = "用户实体")
public class User {
@TableId(type = IdType.AUTO)
@Schema(description = "用户 ID")
private Long id;
@Schema(description = "用户名")
private String username;
@Schema(description = "年龄")
private Integer age;
@Schema(description = "邮箱")
private String email;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserMapper extends BaseMapper <User> {
IPage<User> selectByAge (Page<User> page, @Param("age") Integer age) ;
}
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
@Slf4j
public class UserService extends ServiceImpl <UserMapper, User> {
public boolean createUser (User user) {
user.setCreateTime(LocalDateTime.now());
return save(user);
}
public User getUserById (Long id) {
return getById(id);
}
public List<User> getAllUsers () {
return list();
}
public boolean updateUser (User user) {
return updateById(user);
}
public boolean deleteUser (Long id) {
return removeById(id);
}
public IPage<User> getUsersByPage (int pageNum, int pageSize) {
Page<User> page = new Page <>(pageNum, pageSize);
return page(page);
}
public IPage<User> getUsersByAge (int pageNum, int pageSize, Integer age) {
Page<User> page = new Page <>(pageNum, pageSize);
return baseMapper.selectByAge(page, age);
}
}
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
@SpringBootApplication
@Slf4j
public class DatabaseDemoApplication {
@Autowired
private UserService userService;
public static void main (String[] args) {
SpringApplication.run(DatabaseDemoApplication.class, args);
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor () {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor ();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor ());
return interceptor;
}
@Bean
public CommandLineRunner demo () {
return args -> {
User user = new User ();
user.setUsername("张三" );
user.setAge(25 );
user.setEmail("[email protected] " );
boolean created = userService.createUser(user);
log.info("创建用户:{}" , created ? "成功" : "失败" );
Long userId = user.getId();
log.info("新创建用户 ID: {}" , userId);
User foundUser = userService.getUserById(userId);
log.info("查询到用户:{}" , foundUser);
if (foundUser != null ) {
foundUser.setAge(26 );
boolean updated = userService.updateUser(foundUser);
log.info("更新用户:{}" , updated ? "成功" : "失败" );
}
IPage<User> page = userService.getUsersByPage(1 , 10 );
log.info("分页查询:总记录数={}, 总页数={}" , page.getTotal(), page.getPages());
log.info("当前页数据:{}" , page.getRecords());
IPage<User> agePage = userService.getUsersByAge(1 , 10 , 26 );
log.info("根据年龄查询:{}" , agePage.getRecords());
if (userId != null ) {
boolean deleted = userService.deleteUser(userId);
log.info("删除用户:{}" , deleted ? "成功" : "失败" );
}
};
}
}
Python(使用 PyMySQL 和 SQLAlchemy):
pip install pymysql sqlalchemy
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
import pymysql
DB_CONFIG = {
'host' : 'localhost' ,
'port' : 3306 ,
'user' : 'root' ,
'password' : 'password' ,
'database' : 'test_db' ,
'charset' : 'utf8mb4'
}
engine = create_engine(
f"mysql+pymysql://{DB_CONFIG['user' ]} :{DB_CONFIG['password' ]} @{DB_CONFIG['host' ]} :{DB_CONFIG['port' ]} /{DB_CONFIG['database' ]} ?charset={DB_CONFIG['charset' ]} "
)
Session = sessionmaker(bind=engine)
Base = declarative_base()
class User (Base ):
"""用户模型类"""
__tablename__ = 'user'
id = Column(Integer, primary_key=True , autoincrement=True )
username = Column(String(50 ), nullable=False )
age = Column(Integer)
email = Column(String(100 ))
create_time = Column(DateTime, default=datetime.now)
def __repr__ (self ):
return f"<User(id={self.id } , username='{self.username} ', age={self.age} , email='{self.email} ')>"
Base.metadata.create_all(engine)
def create_user (username, age, email ):
""" 创建用户
@param username: 用户名
@param age: 年龄
@param email: 邮箱
@return: 创建的用户对象
"""
session = Session()
try :
user = User(username=username, age=age, email=email)
session.add(user)
session.commit()
print (f"创建用户成功:{user} " )
return user
except Exception as e:
session.rollback()
print (f"创建用户失败:{str (e)} " )
return None
finally :
session.close()
def get_user_by_id (user_id ):
""" 根据 ID 查询用户
@param user_id: 用户 ID
@return: 用户对象
"""
session = Session()
try :
user = session.query(User).filter_by(id =user_id).first()
if user:
print (f"查询到用户:{user} " )
else :
print (f"未找到 ID 为{user_id} 的用户" )
return user
except Exception as e:
print (f"查询用户失败:{str (e)} " )
return None
finally :
session.close()
def get_all_users ():
""" 查询所有用户
@return: 用户列表
"""
session = Session()
try :
users = session.query(User).all ()
print (f"查询到{len (users)} 个用户" )
return users
except Exception as e:
print (f"查询所有用户失败:{str (e)} " )
return []
finally :
session.close()
def update_user (user_id, **kwargs ):
""" 更新用户信息
@param user_id: 用户 ID
@param kwargs: 要更新的字段
@return: 是否更新成功
"""
session = Session()
try :
user = session.query(User).filter_by(id =user_id).first()
if not user:
print (f"未找到 ID 为{user_id} 的用户" )
return False
for key, value in kwargs.items():
if hasattr (user, key):
setattr (user, key, value)
session.commit()
print (f"更新用户成功:{user} " )
return True
except Exception as e:
session.rollback()
print (f"更新用户失败:{str (e)} " )
return False
finally :
session.close()
def delete_user (user_id ):
""" 根据 ID 删除用户
@param user_id: 用户 ID
@return: 是否删除成功
"""
session = Session()
try :
user = session.query(User).filter_by(id =user_id).first()
if not user:
print (f"未找到 ID 为{user_id} 的用户" )
return False
session.delete(user)
session.commit()
print (f"删除用户成功:ID={user_id} " )
return True
except Exception as e:
session.rollback()
print (f"删除用户失败:{str (e)} " )
return False
finally :
session.close()
def get_users_by_page (page_num=1 , page_size=10 ):
""" 分页查询用户
@param page_num: 页码
@param page_size: 每页大小
@return: 分页用户列表和总记录数
"""
session = Session()
try :
offset = (page_num - 1 ) * page_size
total = session.query(User).count()
users = session.query(User).offset(offset).limit(page_size).all ()
print (f"分页查询:页码={page_num} , 每页大小={page_size} , 总记录数={total} " )
return users, total
except Exception as e:
print (f"分页查询失败:{str (e)} " )
return [], 0
finally :
session.close()
def get_users_by_age (age, page_num=1 , page_size=10 ):
""" 根据年龄分页查询用户
@param age: 年龄
@param page_num: 页码
@param page_size: 每页大小
@return: 分页用户列表和总记录数
"""
session = Session()
try :
offset = (page_num - 1 ) * page_size
total = session.query(User).filter_by(age=age).count()
users = session.query(User).filter_by(age=age).offset(offset).limit(page_size).all ()
print (f"根据年龄查询:年龄={age} , 页码={page_num} , 总记录数={total} " )
return users, total
except Exception as e:
print (f"根据年龄查询失败:{str (e)} " )
return [], 0
finally :
session.close()
if __name__ == "__main__" :
user = create_user("张三" , 25 , "[email protected] " )
if user:
user_id = user.id
get_user_by_id(user_id)
update_user(user_id, age=26 )
users, total = get_users_by_page(1 , 10 )
print (f"当前页用户:{users} " )
age_users, age_total = get_users_by_age(26 )
print (f"年龄为 26 的用户:{age_users} " )
delete_user(user_id)
12. 并发编程:从线程到 Python 的并发模型
12.1 多线程基础 import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@Slf4j
public class MultithreadingDemo {
public static class Counter {
private int count = 0 ;
public synchronized void increment () {
count++;
}
public int getCount () {
return count;
}
}
public static class CountingTask implements Runnable {
private final Counter counter;
private final int iterations;
public CountingTask (Counter counter, int iterations) {
this .counter = counter;
this .iterations = iterations;
}
@Override
public void run () {
String threadName = Thread.currentThread().getName();
log.info("线程 {} 开始执行" , threadName);
for (int i = 0 ; i < iterations; i++) {
counter.increment();
try {
Thread.sleep(1 );
} catch (InterruptedException e) {
log.error("线程 {} 被中断" , threadName);
Thread.currentThread().interrupt();
return ;
}
}
log.info("线程 {} 执行完毕" , threadName);
}
}
public static void main (String[] args) throws InterruptedException {
Counter counter = new Counter ();
int iterationsPerThread = 1000 ;
int threadCount = 5 ;
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
for (int i = 0 ; i < threadCount; i++) {
executor.submit(new CountingTask (counter, iterationsPerThread));
}
executor.shutdown();
if (executor.awaitTermination(1 , TimeUnit.MINUTES)) {
log.info("所有线程执行完毕" );
log.info("最终计数:{} (预期:{})" , counter.getCount(), threadCount * iterationsPerThread);
} else {
log.error("等待超时,仍有线程在运行" );
}
}
}
import threading
import time
from concurrent.futures import ThreadPoolExecutor
class Counter :
"""计数器类"""
def __init__ (self ):
self .count = 0
self .lock = threading.Lock()
def increment (self ):
"""增加计数(线程安全)"""
with self .lock:
self .count += 1
def get_count (self ):
"""获取当前计数"""
return self .count
def counting_task (counter, iterations, thread_name ):
"""计数任务函数"""
print (f"线程 {thread_name} 开始执行" )
for _ in range (iterations):
counter.increment()
time.sleep(0.001 )
print (f"线程 {thread_name} 执行完毕" )
def main ():
counter = Counter()
iterations_per_thread = 1000
thread_count = 5
with ThreadPoolExecutor(max_workers=thread_count) as executor:
for i in range (thread_count):
executor.submit(
counting_task, counter, iterations_per_thread, f"Thread-{i+1 } "
)
print ("所有线程执行完毕" )
print (f"最终计数:{counter.get_count()} (预期:{thread_count * iterations_per_thread} )" )
if __name__ == "__main__" :
main()
12.2 Python 的 GIL 与多进程 由于 Python 的全局解释器锁(GIL),多线程在 CPU 密集型任务中并不能真正并行。对于这类任务,应该使用多进程:
import multiprocessing
import time
def cpu_intensive_task (start, end ):
"""CPU 密集型任务:计算从 start 到 end 的和"""
process_name = multiprocessing.current_process().name
print (f"进程 {process_name} 开始执行:计算 {start} 到 {end} 的和" )
total = 0
for i in range (start, end):
total += i
print (f"进程 {process_name} 执行完毕,结果:{total} " )
return total
def main ():
ranges = [
(1 , 25000000 ),
(25000000 , 50000000 ),
(50000000 , 75000000 ),
(75000000 , 100000000 )
]
start_time = time.time()
with multiprocessing.Pool(processes=4 ) as pool:
results = pool.starmap(cpu_intensive_task, ranges)
total = sum (results)
end_time = time.time()
print (f"所有进程执行完毕,总和:{total} " )
print (f"总耗时:{end_time - start_time:.2 f} 秒" )
if __name__ == "__main__" :
main()
13. 实战项目:简易 RESTful API 服务
13.1 Java 版本(Spring Boot + Spring MVC) <dependencies >
<dependency >
<groupId > org.projectlombok</groupId >
<artifactId > lombok</artifactId >
<version > 1.18.30</version >
<scope > provided</scope >
</dependency >
<dependency >
<groupId > org.slf4j</groupId >
<artifactId > slf4j-api</artifactId >
<version > 2.0.9</version >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
<version > 3.1.3</version >
</dependency >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-validation</artifactId >
<version > 3.1.3</version >
</dependency >
<dependency >
<groupId > org.springdoc</groupId >
<artifactId > springdoc-openapi-starter-webmvc-ui</artifactId >
<version > 2.1.0</version >
</dependency >
</dependencies >
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.Data;
@Data
@Schema(description = "用户实体")
public class User {
@Schema(description = "用户 ID", example = "1")
private Long id;
@NotBlank(message = "用户名不能为空")
@Schema(description = "用户名", example = "张三")
private String username;
@PositiveOrZero(message = "年龄不能为负数")
@Schema(description = "年龄", example = "25")
private Integer age;
@Email(message = "邮箱格式不正确")
@Schema(description = "邮箱", example = "[email protected] ")
private String email;
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@Service
@Slf4j
public class UserService {
private final Map<Long, User> userMap = new ConcurrentHashMap <>();
private final AtomicLong idGenerator = new AtomicLong (1 );
public User createUser (User user) {
log.info("创建用户:{}" , user);
Long userId = idGenerator.getAndIncrement();
user.setId(userId);
userMap.put(userId, user);
return user;
}
public User getUserById (Long id) {
log.info("查询用户:ID={}" , id);
return userMap.get(id);
}
public List<User> getAllUsers () {
log.info("查询所有用户" );
Collection<User> users = userMap.values();
return CollectionUtils.isEmpty(users) ? Collections.emptyList() : new ArrayList <>(users);
}
public User updateUser (Long id, User user) {
log.info("更新用户:ID={}, 新信息={}" , id, user);
if (!userMap.containsKey(id)) {
return null ;
}
User existingUser = userMap.get(id);
if (user.getUsername() != null ) {
existingUser.setUsername(user.getUsername());
}
if (user.getAge() != null ) {
existingUser.setAge(user.getAge());
}
if (user.getEmail() != null ) {
existingUser.setEmail(user.getEmail());
}
userMap.put(id, existingUser);
return existingUser;
}
public boolean deleteUser (Long id) {
log.info("删除用户:ID={}" , id);
return userMap.remove(id) != null ;
}
}
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
@Slf4j
@Tag(name = "用户管理", description = "用户 CRUD 操作的 API 接口")
public class UserController {
private final UserService userService;
public UserController (UserService userService) {
this .userService = userService;
}
@PostMapping
@Operation(summary = "创建用户", description = "添加新用户到系统")
@ApiResponses({
@ApiResponse(responseCode = "201", description = "用户创建成功", content = @Content(schema = @Schema(implementation = User.class))),
@ApiResponse(responseCode = "400", description = "请求参数错误")
})
public ResponseEntity<User> createUser (
@Valid @RequestBody @Parameter(description = "用户信息") User user) {
User createdUser = userService.createUser(user);
return new ResponseEntity <>(createdUser, HttpStatus.CREATED);
}
@GetMapping("/{id}")
@Operation(summary = "查询用户", description = "根据 ID 查询用户信息")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "查询成功", content = @Content(schema = @Schema(implementation = User.class))),
@ApiResponse(responseCode = "404", description = "用户不存在")
})
public ResponseEntity<User> getUserById (
@PathVariable @Parameter(description = "用户 ID") Long id) {
User user = userService.getUserById(id);
if (user == null ) {
return new ResponseEntity <>(HttpStatus.NOT_FOUND);
}
return ResponseEntity.ok(user);
}
@GetMapping
@Operation(summary = "查询所有用户", description = "获取系统中所有用户的列表")
@ApiResponse(responseCode = "200", description = "查询成功", content = @Content(schema = @Schema(implementation = User.class)))
public ResponseEntity<List<User>> getAllUsers () {
List<User> users = userService.getAllUsers();
return ResponseEntity.ok(users);
}
@PutMapping("/{id}")
@Operation(summary = "更新用户", description = "根据 ID 更新用户信息")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "更新成功", content = @Content(schema = @Schema(implementation = User.class))),
@ApiResponse(responseCode = "400", description = "请求参数错误"),
@ApiResponse(responseCode = "404", description = "用户不存在")
})
public ResponseEntity<User> updateUser (
@PathVariable @Parameter(description = "用户 ID") Long id,
@Valid @RequestBody @Parameter(description = "更新的用户信息") User user) {
User updatedUser = userService.updateUser(id, user);
if (updatedUser == null ) {
return new ResponseEntity <>(HttpStatus.NOT_FOUND);
}
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
@Operation(summary = "删除用户", description = "根据 ID 删除用户")
@ApiResponses({
@ApiResponse(responseCode = "204", description = "删除成功"),
@ApiResponse(responseCode = "404", description = "用户不存在")
})
public ResponseEntity<Void> deleteUser (
@PathVariable @Parameter(description = "用户 ID") Long id) {
boolean deleted = userService.deleteUser(id);
if (!deleted) {
return new ResponseEntity <>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity <>(HttpStatus.NO_CONTENT);
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
@SpringBootApplication
@OpenAPIDefinition(
info = @Info(
title = "用户管理 API",
version = "1.0",
description = "简易用户管理系统的 RESTful API 接口文档"
)
)
public class RestApiApplication {
public static void main (String[] args) {
SpringApplication.run(RestApiApplication.class, args);
}
}
13.2 Python 版本(FastAPI) pip install fastapi uvicorn pydantic
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel, EmailStr, field_validator
from typing import List , Optional , Dict
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI(
title="用户管理 API" ,
description="简易用户管理系统的 RESTful API 接口" ,
version="1.0.0"
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*" ],
allow_credentials=True ,
allow_methods=["*" ],
allow_headers=["*" ],
)
class User (BaseModel ):
"""用户模型"""
id : Optional [int ] = None
username: str
age: Optional [int ] = None
email: Optional [EmailStr] = None
@field_validator('age' )
def age_must_be_non_negative (cls, v ):
"""验证年龄必须为非负数"""
if v is not None and v < 0 :
raise ValueError('年龄不能为负数' )
return v
users: Dict [int , User] = {}
next_id = 1
@app.post("/api/users" , response_model=User, status_code=status.HTTP_201_CREATED )
def create_user (user: User ):
""" 创建新用户
@param user: 用户信息
@return: 创建的用户对象(包含 ID)
"""
global next_id
logger.info(f"创建用户:{user} " )
user.id = next_id
users[next_id] = user
next_id += 1
return user
@app.get("/api/users/{user_id}" , response_model=User )
def get_user (user_id: int ):
""" 根据 ID 查询用户
@param user_id: 用户 ID
@return: 用户对象
"""
logger.info(f"查询用户:ID={user_id} " )
if user_id not in users:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"用户 ID {user_id} 不存在"
)
return users[user_id]
@app.get("/api/users" , response_model=List [User] )
def get_all_users ():
""" 查询所有用户
@return: 用户列表
"""
logger.info("查询所有用户" )
return list (users.values())
@app.put("/api/users/{user_id}" , response_model=User )
def update_user (user_id: int , user_update: User ):
""" 更新用户信息
@param user_id: 用户 ID
@param user_update: 包含更新信息的用户对象
@return: 更新后的用户对象
"""
logger.info(f"更新用户:ID={user_id} , 新信息={user_update} " )
if user_id not in users:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"用户 ID {user_id} 不存在"
)
existing_user = users[user_id]
if user_update.username is not None :
existing_user.username = user_update.username
if user_update.age is not None :
existing_user.age = user_update.age
if user_update.email is not None :
existing_user.email = user_update.email
users[user_id] = existing_user
return existing_user
@app.delete("/api/users/{user_id}" , status_code=status.HTTP_204_NO_CONTENT )
def delete_user (user_id: int ):
""" 根据 ID 删除用户
@param user_id: 用户 ID
"""
logger.info(f"删除用户:ID={user_id} " )
if user_id not in users:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"用户 ID {user_id} 不存在"
)
del users[user_id]
return None
if __name__ == "__main__" :
uvicorn.run(app, host="0.0.0.0" , port=8000 )
14. Java 与 Python 的核心差异总结 特性 Java Python 类型系统 静态类型,编译时检查 动态类型,运行时检查 语法风格 强调显式声明,使用大括号和分号 简洁,使用缩进来划分代码块 性能 编译为字节码,性能较好 解释执行,通常性能较低 并发模型 多线程,真正并行 受 GIL 限制,多线程不适合 CPU 密集型任务,常用多进程 生态系统 强大的企业级库,Spring 生态 丰富的数据科学、AI 库,简洁的 Web 框架 代码量 相对冗长 简洁,代码量通常较少 学习曲线 较陡峭 较平缓,易于上手 应用场景 企业级应用,Android 开发 数据分析,AI,脚本,快速原型开发
15. 总结与下一步学习建议 通过本教程,我们从 Java 开发者的视角快速了解了 Python 的核心语法和特性。我们对比了两种语言在数据类型、控制流、函数、面向对象、异常处理、文件操作、数据库访问和并发编程等方面的异同。
作为 Java 开发者,学习 Python 有以下优势:
可以快速理解面向对象概念,只需适应 Python 的语法差异
熟悉的编程思想(如封装、继承、多态)在 Python 中同样适用
已有的数据库和网络编程知识可以迁移应用
深入学习 Python 特有的高级特性:装饰器、生成器、上下文管理器等
探索 Python 丰富的第三方库:NumPy/Pandas(数据分析)、Django/Flask(Web 开发)、TensorFlow/PyTorch(机器学习)
实践更多项目,如 Web 服务、数据处理脚本、自动化工具等
学习 Python 的测试框架(如 pytest)和代码规范(PEP 8)
Python 以其简洁、灵活和强大的生态系统,为开发者提供了另一种高效的编程选择。作为 Java 开发者,掌握 Python 不仅能拓宽技术视野,更能在合适的场景下选择最适合的工具,提高开发效率。
相关免费在线工具 RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online