网站建设怎么设置多语言易思企业网站破解版
2026/3/16 12:46:14 网站建设 项目流程
网站建设怎么设置多语言,易思企业网站破解版,重庆网站建设 最便宜,国外代理服务器免费文章目录一、核心差异概览二、关键语法对比1、基础结构对比2、数据类型对应表3、集合操作对比三、面向对象编程差异1、类定义对比2、访问控制对比四、异常处理对比五、方法与函数对比1、函数定义差异2、Lambda 表达式对比六、并发编程对比1、多线程对比2、异步编程对比七、Java…文章目录一、核心差异概览二、关键语法对比1、基础结构对比2、数据类型对应表3、集合操作对比三、面向对象编程差异1、类定义对比2、访问控制对比四、异常处理对比五、方法与函数对比1、函数定义差异2、Lambda 表达式对比六、并发编程对比1、多线程对比2、异步编程对比七、Java 开发者常见陷阱1、可变默认参数2、相等性比较3、循环变量作用域4、浅拷贝与深拷贝八、实用工具对比九、Pythonic 编程风格1. 列表推导式替代循环2. 使用生成器节省内存3. 上下文管理器替代try-finally4. 使用枚举Enum十、wheel pyproject.toml 案例工具概述案例编写 pyproject.toml 文件编写 my_math.py编写 README.md构建 Wheel 包参考 目标非常熟悉 Java 的开发者想要快速转换到 Python 开发。一、核心差异概览维度Java 语言Python 语言类型系统静态强类型编译时检查动态强类型运行时检查语法风格显式声明分号结束大括号代码块缩进定义块简洁语法执行方式编译为 class 字节码JVM 运行解释执行也有字节码编译性能特点通常更快尤其计算密集型开发速度快标准场景够用哲学理念“明确优于隐晦”提供多种明确选择“做一件事只有一种明显的方式”约定优于配置包管理Maven/Gradle依赖管理严格pip pyproject.toml更灵活并发模型基于线程JVM 管理GIL 限制多进程/asyncio 怎么理解呢1、类型系统Java 中的所有类型都需要在编写代码时定义好类型称之为静态强类型。Python 则不同直接声明变量不需要指定类型其类型是动态的。2、语法风格Java 必须分号结束用大括号表示代码块。Python 中则不需要分号直接定义缩进来实现代码块。3、执行方式Java 是编译型语言先编写源文件.java然后使用 javac 编译为字节码 .class文件最后 JVM 加载字节码来运行。Python 则是解释型语言直接利用解释器解释并执行。也有字节码编译Jython。4、性能特点Java 性能高于 PythonJava 适合 CPU 密集型任务一般是企业级开发常用语言。Python 开发速度快标准场景够用。5、哲学理念Java 中提供多种解决方案来解决一件事情。Python 有 Pythonic 哲学。6、包管理Java 一般使用 Ant、Maven、Gradle 管理依赖。Python 使用 pip pyproject.toml 管理依赖。7、并发模型Java 支持多种创建线程的方式含线程池JVM 会管理线程。Python 的多线程会受到 Global Interpreter Lock 这个全局锁的限制导致多线程实际运行变成了串行执行适合 IO 密集型的任务。二、关键语法对比1、基础结构对比Java 中会定义一个类在类中使用 main() 方法来运行程序。publicclassHello{publicstaticvoidmain(String[]args){System.out.println(Hello);intx5;StringnameJava;if(x0){System.out.println(Positive);}}}Python 中可以写一个入口函数类似于 main 方法。写法上更加简洁不需要静态指定类型使用缩进来替代大括号。直呼简洁defmain():print(Hello)# 简洁输出x5# 不需要声明类型namePython# 不需要声明类型ifx0:# 缩进替代大括号print(x is positive)# 类似main方法的入口if__name____main__:main()2、数据类型对应表Java 类型Python 类型关键差异intlongintPython 整数无大小限制自动处理大数floatdoublefloatPython 只有双精度浮点数booleanbooltrue - Truefalse - Falsecharstr长度 1Python 没有单独的字符类型StringstrPython 的字符串不可变同 JavaArrayListlistPython 列表可包含不同类型元素LinkedListcollections.deque双端队列使用双向链表实现HashMapK, Vdict键值对集合语法更简洁HashSetset无序不重复集合T[]list 或 tuple元组不可变列表可变nullNonePython 的空值对象 怎么理解呢1、int、long 类型Java 处理大数就不能用 int得换成 BigInteger 了。Python 的 int 特别牛逼自动处理大数。2、floatdouble 类型Java 有单精度和双精度浮点数。Python 直接就是双精度浮点数。3、boolean 类型Java 的布尔值是 true 和 false。Python 的布尔值是 True 和 False变成大写开头了。4、char 类型Java 有字符类型。Python 直接就是字符串类型只是长度为 1 罢了。5、String 类型Java 和 Python 的字符串都是不可变的。6、ArrayListJava 中的线性表。Python 中不需要静态定义类型直接 list 即可。7、LinkedListJava 中的链表。Python 中使用 collections.deque 双端队列Double-Ended Queue其本质是双向链表实现的可以实现链表的所有功能。8、HashMapK, VJava 中的键值对是 Map。Python 中使用 dict 字典来实现按 key 来存储 value。9、HashSetJava 中的集合。Python 使用 set 来实现。集合是数学中的集合里面的元素唯一。10、T[]Java 中的对象数组。Python 可以使用 list 列表实现或者 tuple 元组来实现。需注意的是元组 tuple 是不可变的其内部元素的引用不可变。11、nullJava 中的 null。Python 中是 None。3、集合操作对比Java 中 List、Map、Set以及迭代方式importjava.util.*;publicclassCollectionExample{publicstaticvoidmain(String[]args){// ListListStringlistnewArrayList();list.add(Java);list.add(Python);Stringfirstlist.get(0);intsizelist.size();// MapMapString,IntegerscoresnewHashMap();scores.put(Alice,95);scores.put(Bob,87);IntegeraliceScorescores.get(Alice);// SetSetIntegeruniqueNumbersnewHashSet();uniqueNumbers.add(1);uniqueNumbers.add(2);uniqueNumbers.add(1);// 重复不会添加// 迭代for(Stringitem:list){System.out.println(item);}for(Map.EntryString,Integerentry:scores.entrySet()){System.out.println(entry.getKey(): entry.getValue());}}}Python 中对应 list、dict、set 的基本操作、迭代。同时 Python 特有的推导式 切片数据获取。defmain():#### 列表、字典、集合的基本操作 ##### 列表类似于ArrayListmy_list[]# 或 list()my_list.append(Java)my_list.append(Python)my_list.insert(1,C)first_itemmy_list[0]last_itemmy_list[-1]lengthlen(my_list)print(列表,my_list)print(列表第一个元素,first_item)print(列表最后一个元素,last_item)print(列表长度,length)print()# 字典类似HashMapscores{}# 或 dict()scores[张三]95scores[李四]87zhangsan_scorescores.get(张三)# 安全访问lisi_scorescores[李四]# 直接访问如果不存在会报错KeyErrorprint(字典,scores)print(张三的成绩,zhangsan_score)print(李四的成绩,lisi_score)try:wang_scorescores[王二五]exceptKeyError:print(王二五的成绩不存在)print()# 集合类似于HashSetunique_numbersset()unique_numbers.add(1)unique_numbers.add(2)unique_numbers.add(2)# 重复不会被添加print(集合,unique_numbers)print()#### 迭代操作 ##### 列表常规迭代foriteminmy_list:print(item)print()# 列表带索引的迭代forindex,iteminenumerate(my_list):print(findex{index}{item})print()# 字典迭代forkey,valueinscores.items():print(f{key}{value})print()# 同时迭代多个序列names[张三,李四,王二五]ages[25,30,35]forname,ageinzip(names,ages):print(f{name}is{age}years old)#### Python特有推导式 切片 ##### 列表推导式## range(10)生成0~9的整数序列## for x in ...上面的序列进行遍历每次取出一个值赋给x## if x % 2 0 是筛选条件x的值必须是偶数## x**2 是输出表达式对符合要求的x取平方运算squares[x**2forxinrange(10)ifx%20]print(squares)# [0, 4, 16, 36, 64]# 字典推导式## x从0~4遍历## x: x**2 是字典项的构造规则square_dict{x:x**2forxinrange(5)}print(square_dict)# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}# 集合推导式square_chars{charforcharinhello worldifchar! }print(square_chars)# {e, o, l, w, r, d, h}# 切片操作Python特有## 基本语法list[start:stop:step]## start起始索引包含该位置不填则默认为0## stop 结束索引不包含该位置不填则默认为列表长度## step 步长下取位置 当前位置 步长numbers[xforxinrange(10)]# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]first_threenumbers[:3]last_threenumbers[-3:]middlenumbers[2:6]# [2, 3, 4, 5]every_othernumbers[::2]# [0, 2, 4, 6, 8]reversed_listnumbers[::-1]print(numbers)print(f前三个{first_three})print(f后三个{last_three})print(f中间的{middle})print(f偶数位{every_other})print(f反序{reversed_list})if__name____main__:main()Python 中特有的元组示例和列表的区别是元组是不可变的。# 1、创建元组使用圆括号而非中括号t1(1,2,Hello,True)# 元组(1, 2, Hello, True)类型class tupleprint(f元组{t1}类型{type(t1)})# 特例只有一个元素的元组必须加逗号t_one(1,)t_num(1)print(f(1,)的类型{type(t_one)})# (1,)的类型class tupleprint(f(1)的类型{type(t_num)})# (1)的类型class int# 2、访问元素同listprint(ft1的第一个元素{t1[0]})# t1的第一个元素1print(ft1切面:{t1[1:3]})# t1切面: (2, Hello)# 3、不可变性核心特征即元组的值定义后不可修改。try:t1[0]999exceptTypeErrorase:print(f修改元组数据报错{e})# 修改元组数据报错tuple object does not support item assignment# 4、可变的元组如果元组中包含可变对象比如列表则列表是可变的。t_mutable(1,[2,3])t_mutable[1].append(4)# 元组引用的指向没有变所以可以修改print(f元组{t_mutable})# 元组(1, [2, 3, 4])# 5、元组解包 - 非常有用point(10,20)x,ypoint# 自动把元组中的值赋给变量print(fx{x}, y{y})# x10, y20三、面向对象编程差异Java 是面向对象编程语言Python 同样支持面向对象编程。1、类定义对比Java 中定义一个类私有属性、构造方法、静态属性、私有属性的 setter/getter 方法、实例方法、静态方法、方法覆盖、类的继承机制。// JavapublicclassPerson{// 字段privateStringname;privateintage;publicstaticintcount0;// 构造方法publicPerson(Stringname,intage){this.namename;this.ageage;count;}// 实例方法publicStringgetName(){returnthis.name;}publicvoidsetName(Stringname){this.namename;}publicvoidgreet(){System.out.println(Hello, Im name);}// 静态方法publicstaticintgetCount(){returncount;}// toString方法OverridepublicStringtoString(){returnString.format(Person{name%s, age%d},name,age);}}// 继承publicclassEmployeeextendsPerson{privateStringemployeeId;publicEmployee(Stringname,intage,StringemployeeId){super(name,age);this.employeeIdemployeeId;}Overridepublicvoidgreet(){System.out.println(Hello, Im employee employeeId);}}Python 中同样支持上述能力且代码更加简洁。classPerson:# 类变量类似于静态变量count0# 构造方法非必须可省略def__init__(self,name:str,age:int0):初始化方法类似Java构造器self.namename# 会调用后面的setter方法self.ageage self._protected_varprotected# 单下划线表示protectedself.__private_varprivate# 双下划线表示privatePerson.count1# 属性装饰器类似于getterpropertydefname(self)-str:returnself._name# setter方法name.setterdefname(self,value:str):ifnotvalue:raiseValueError(Name cannot be empty)self._namevalue# 实例方法self类似于thisdefgreet(self)-str:returnfHello, my name is{self.name}and I am{self.age}years old.# 类方法classmethoddefget_count(cls)-int:类方法第一个参数是cls表示类本身returncls.count# 静态方法staticmethoddefis_audit(age:int)-bool:静态方法无需self或cls参数returnage18# 特殊方法类似于Java中的toString## str给用户看的可读性好样式美观def__str__(self)-str:returnfPerson(name{self.name}, age{self.age})## repr给开发者看的准确性高消除歧义【默认会使用repr】def__repr__(self)-str:returnfPerson({self.name},{self.age})# 继承classEmployee(Person):def__init__(self,name:str,age:int,employee_id:str):# 调用父类的构造方法super().__init__(name,age)self.employee_idemployee_id# 方法重写defgreet(self)-str:returnfHello, I am employee{self.employee_id}.# 方法重写def__str__(self)-str:returnfEmployee(name{self.name}, id{self.employee_id})if__name____main__:# 创建实例personPerson(张三,20)print(str(person))# 获取属性值print(person.name)print(person.age)# 设置属性值person.name张三2# 直接赋值会自动触发setterperson.age23# 直接赋值就是个普通的公开实例变量print(str(person))# Person(name张三2, age23)# 调用方法实例方法、类方法、静态方法print(person.greet())# Hello, my name is 张三2 and I am 23 years old.print(Person.get_count())# 1print(Person.is_audit(18))# True# 特殊方法调用print(str(person))# Person(name张三2, age23)print(repr(person))# Person(张三2, 23)# 继承employeeEmployee(李四,30,EMP001)# 类型检查print(isinstance(employee,Person))# Trueprint(isinstance(employee,Employee))# Trueprint(type(employee))# class __main__.Employee# 继承中的方法重写print(employee.greet())# Hello, I am employee EMP001.print(str(employee))# Employee(name李四, idEMP001)print(repr(employee))# Person(李四, 30)2、访问控制对比访问控制JavaPython公共public无修饰符默认保护protected_单下划线约定非强制私有private__双下划线名称修饰包私有无修饰符无对应概念四、异常处理对比Java 中的异常处理包括捕获异常、抛出异常、自定义异常等功能。 try-catch-finally// Javaimportjava.io.*;publicclassExceptionExample{publicstaticvoidmain(String[]args){try{// 可能抛出异常的代码BufferedReaderreadernewBufferedReader(newFileReader(file.txt));Stringlinereader.readLine();System.out.println(line);reader.close();// 自定义异常intresultdivide(10,0);}catch(FileNotFoundExceptione){System.err.println(文件未找到: e.getMessage());}catch(IOExceptione){System.err.println(IO错误: e.getMessage());}catch(ArithmeticExceptione){System.err.println(算术错误: e.getMessage());}finally{System.out.println(清理资源);}}publicstaticintdivide(inta,intb)throwsArithmeticException{if(b0){thrownewArithmeticException(除数不能为零);}returna/b;}}Python 中也支持异常处理无非是语法不同。try-except-else-finally其中 else 表示 try 过程中没有异常产生且没有 return 返回值时执行。importrandomdefdivide(a:int,b:int)-float:除法运算ifb0:# 显式抛出 ValueError更具语义化raiseValueError(除数不能为0)returna/bdefread_file(filename:str)-str:读取文件内容content# 初始化默认值防止作用域问题try:# 自动资源管理withopen(filename,r,encodingutf-8)asf:contentf.read()# 模拟业务逻辑resultdivide(10,random.randint(0,1))print(f除法结果{result})exceptFileNotFoundErrorase:print(f文件{filename}未找到,{e})raise# 向上抛出让调用者感知except(IOError,PermissionError)ase:print(fIO错误:{e})return# 吞掉异常返回空串exceptValueErrorase:# 对应 divide 函数抛出的 ValueErrorprint(f计算逻辑错误:{e})returnexceptExceptionase:# 兜底捕获print(f未知异常:{e})returnelse:# 只有 try 块完全成功无异常且无 return才执行print(f文件{filename}读取及计算均成功)returncontentfinally:# 无论成功失败都会执行print(finally 语句块无论是否发生异常都会执行)classMyCustomException(Exception):自定义异常类def__init__(self,message:str,error_code:int):super().__init__(message)self.error_codeerror_codedef__str__(self)-str:# self.args[0]是父类Exception存储message的地方returnf{self.args[0]}错误码{self.error_code}if__name____main__:try:# 创建一个测试文件方便演示成功情况withopen(1.txt,w,encodingutf-8)asf:f.write(Hello Python Exception)file_contentread_file(1.txt)print(f文件内容:{file_content})exceptExceptionase:print(f主程序捕获异常:{e})# 自定义异常捕获try:raiseMyCustomException(数据库连接异常,500)exceptMyCustomExceptionase:print(e)五、方法与函数对比Java 中称之为方法Python 中称之为函数。1、函数定义差异Java 方法方法名称、方法参数、方法返回值、静态方法、可变参数、方法重载等能力。// JavapublicclassMathUtils{// 必须指定返回类型void表示无返回值publicstaticintadd(inta,intb){returnab;}// 可变参数publicstaticintsum(int...numbers){inttotal0;for(intnum:numbers){totalnum;}returntotal;}// 方法重载publicstaticdoubleadd(doublea,doubleb){returnab;}}Python 函数同样地。多加了关键字参数、参数解包能力。# Python 函数defadd(a:int,b:int)-int:加法函数 参数 a第一个加数 b第二个加数 返回值 两个加数的和 returnab# 参数带默认值defgeeet(name:str,greeting:strHello)-str:问候函数returnf{greeting},{name}# 可变参数类似于Java中的...defsum_all(*args:int)-int:计算所有参数的和returnsum(args)# 关键字参数defcreate_person(**kwargs)-dict:创建一个Person对象person{name:kwargs.get(name,unknown),age:kwargs.get(age,0),city:kwargs.get(city,unknown)}returnperson# 参数组合参数、参数带默认值、可变参数、关键字参数defcomplex_function(a,b10,*args,**kwargs):复杂的参数组合print(fa{a}, b{b})ifargs:print(f额外位置参数:{args})ifkwargs:print(f关键字参数:{kwargs})if__name____main__:print(add(1,1));print(geeet(张三))print(geeet(张三,您好))print(sum_all(1,2,3,4,5))personcreate_person(name张三,age25,city上海)print(person)# 参数解包## 如果直接传入相当于传入了一个列表是一个参数## 利用解包可以将列表元素解开变成多个参数传入numbers[1,2,3,4,5]print(sum_all(*numbers))## 同样地解包后相当于 create_person(name张三, age30)params{name:张三,age:30}print(create_person(**params))2、Lambda 表达式对比Java 提供 Lambda 表达式。// Java 8ListStringnamesArrays.asList(Alice,Bob,Charlie);names.sort((a,b)-a.compareTo(b));names.forEach(name-System.out.println(name));// 函数式接口FunctionInteger,Integersquarex-x*x;intresultsquare.apply(5);// 25Python 同样支持 Lambda 表达式。# Python Lambda匿名函数names[Alice,Bob,Charlie]names.sort(keylambdax:x.lower())# 忽略大小写排序# 使用lambdasquaredlist(map(lambdax:x**2,[1,2,3,4]))# [1, 4, 9, 16]# 过滤even_numberslist(filter(lambdax:x%20,range(10)))# [0, 2, 4, 6, 8]# 排序复杂对象people[{name:Alice,age:25},{name:Bob,age:30},{name:Charlie,age:20}]people.sort(keylambdap:p[age])# 按年龄排序六、并发编程对比1、多线程对比Java 中创建线程继承 Thread、实现 Runnable 接口、使用线程池等方式。// JavapublicclassThreadExample{publicstaticvoidmain(String[]args){// 继承Thread类classMyThreadextendsThread{Overridepublicvoidrun(){System.out.println(Thread running: Thread.currentThread().getId());}}// 实现Runnable接口classMyRunnableimplementsRunnable{Overridepublicvoidrun(){System.out.println(Runnable running: Thread.currentThread().getId());}}// 创建线程Threadthread1newMyThread();Threadthread2newThread(newMyRunnable());thread1.start();thread2.start();// 使用线程池ExecutorServiceexecutorExecutors.newFixedThreadPool(5);for(inti0;i10;i){executor.submit(()-{System.out.println(Task executed by: Thread.currentThread().getName());});}executor.shutdown();}}Python 多线程受 GIL 限制1、在标准 PythonCPython中多线程不能利用多核 CPU 进行并行计算同一时刻只能有一个线程在执行 Python 字节码。2、什么是 GILGlobal Interpreter Lock全局解释器锁是一把大锁它是 Python 解释器设计上的一个限制。作用保护 Python 解释器的内部内存管理不是线程安全的规则任何 Python 线程想要执行代码CPU 密集型任务必须先拿到这把锁流程如果多线程去跑那么同一时刻只有一个线程在跑其它线程等待本质上是串行3、Python 多线程没用有用仅限于 I/O 密集型任务。比如写爬虫、请求 API、读取数据库时Python 多线程效率很高。4、总结计算密集型CPU 密集型不要使用多线程会被 GIL 锁死要用多进程。I/O 密集型等网络/磁盘可以用多线程GIL 影响不大。importthreadingimporttimedefprint_numbers():打印数字foriinrange(5):print(fNumber{i}from{threading.current_thread().name})time.sleep(0.1)defprint_letters():打印字母forletterin[A,B,C,D,E]:print(fLetter:{letter}from{threading.current_thread().name})time.sleep(0.1)if__name____main__:# 方法1: 直接创建线程thread1threading.Thread(targetprint_numbers,nameNumbersThread)thread2threading.Thread(targetprint_letters,nameLettersThread)thread1.start()thread2.start()thread1.join()thread2.join()# 执行结果很尴尬吧就是串行执行的...# Number0 from NumbersThread# Letter: A from LettersThread# Number1 from NumbersThread# Letter: B from LettersThread# Number2 from NumbersThread# Letter: C from LettersThread# Number3 from NumbersThread# Letter: D from LettersThread# Number4 from NumbersThread# Letter: E from LettersThread# 所有线程执行完毕print(所有线程执行完毕)Python 线程池示例同样地多线程执行变成了串行执行。importthreadingimporttimefromconcurrent.futuresimportThreadPoolExecutordefprint_numbers():打印数字foriinrange(5):print(fNumber{i}from{threading.current_thread().name})time.sleep(0.1)if__name____main__:# 方法2: 使用线程池推荐withThreadPoolExecutor(max_workers3)asexecutor:# 提交任务futures[]foriinrange(5):futureexecutor.submit(print_numbers)futures.append(future)# 等待所有任务完成forfutureinfutures:future.result()输出结果从如下结果来看也能看出是串行执行。。。# 前面3个任务使用3个线程每个线程里循环输出5次共15次Number0fromThreadPoolExecutor-0_0 Number0fromThreadPoolExecutor-0_1 Number0fromThreadPoolExecutor-0_2 Number1fromThreadPoolExecutor-0_0 Number1fromThreadPoolExecutor-0_1 Number1fromThreadPoolExecutor-0_2 Number2fromThreadPoolExecutor-0_0 Number2fromThreadPoolExecutor-0_2 Number2fromThreadPoolExecutor-0_1 Number3fromThreadPoolExecutor-0_0 Number3fromThreadPoolExecutor-0_2 Number3fromThreadPoolExecutor-0_1 Number4fromThreadPoolExecutor-0_0 Number4fromThreadPoolExecutor-0_1 Number4fromThreadPoolExecutor-0_2# 最后还剩2个任务只需要使用2个线程Number0fromThreadPoolExecutor-0_0 Number0fromThreadPoolExecutor-0_1 Number1fromThreadPoolExecutor-0_0 Number1fromThreadPoolExecutor-0_1 Number2fromThreadPoolExecutor-0_0 Number2fromThreadPoolExecutor-0_1 Number3fromThreadPoolExecutor-0_0 Number3fromThreadPoolExecutor-0_1 Number4fromThreadPoolExecutor-0_0 Number4fromThreadPoolExecutor-0_1Python 互斥锁加锁使得某一时刻只有一个线程能拿到锁能进行操作。importthreadingif__name____main__:线程同步通过互斥锁Lock来保证多线程安全地修改同一个共享变量# 创建一把互斥锁lockthreading.Lock()# 共享变量shared_counter0defincrement_counter():globalshared_counter# 通过with语句自动获取和释放锁等同于lock.acquire()和lock.release()## 确保同一时刻只有一个线程可以执行临界区withlock:for_inrange(1000):shared_counter1# 创建多个线程修改共享变量threads[]for_inrange(10):threadthreading.Thread(targetincrement_counter)threads.append(thread)thread.start()forthreadinthreads:thread.join()print(f最终计数器值:{shared_counter})# 应该是100002、异步编程对比Java 异步编程异步提交任务然后获取执行结果。// Javaimportjava.util.concurrent.*;publicclassAsyncExample{publicstaticvoidmain(String[]args)throwsException{ExecutorServiceexecutorExecutors.newFixedThreadPool(2);CompletableFutureStringfutureCompletableFuture.supplyAsync(()-{try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}returnHello;},executor).thenApply(result-{returnresult World;}).thenAccept(result-{System.out.println(Result: result);});future.get();// 等待完成executor.shutdown();}}Python 异步编程和 Java 很相似使用 async await 关键字实现。# Python 异步编程importasyncioimportaiohttpasyncdeffetch_url(url:str)-str:异步获取URL内容 1、async def 定义了一个协程coroutine函数它不会立即执行而是返回一个协程对象。 这种函数可以在等待耗时比如http请求操作时让出CPU让其他任务执行。而不是像普通函数那样阻塞等待。 2、async with 是异步版本的上下文管理器保证在进入和退出代码块时正确地初始化和关闭资源 3、async with session.get(url) 异步http请求并非直接拿到响应体而只是拿到响应头确认连接建立。 4、return await response.text() 这里await是异步编程的关键它会让出CPU让其他任务执行。 等下载完成后在叫醒我继续往下执行。 asyncwithaiohttp.ClientSession()assession:asyncwithsession.get(url)asresponse:returnawaitresponse.text()asyncdefprocess_data(data:str)-dict:异步处理数据awaitasyncio.sleep(1)# 模拟耗时操作return{length:len(data),processed:True}asyncdefmain():主异步函数urls[https://www.java.com,https://www.python.org]# 创建任务tasks[fetch_url(url)forurlinurls]# 并发执行任务## 异步任务并行执行且出现异常时返回一个异常对象而不是程序报错resultsawaitasyncio.gather(*tasks,return_exceptionsTrue)# 处理结果forurl,resultinzip(urls,results):ifisinstance(result,Exception):print(fError fetching{url}:{result})else:processedawaitprocess_data(result)print(fProcessed{url}:{processed})# 运行异步程序if__name____main__:# 执行协程coroutine并获得结果asyncio.run(main())七、Java 开发者常见陷阱1、可变默认参数Python 方法中默认参数值是可变的 Default argument value is mutable。也就意味着如果你在参数默认值中定义一个列表那么这个列表其实就是共享的# ❌ 错误做法可变对象作为默认参数defbad_function(items[]):# 默认列表在函数定义时创建所有调用共享items.append(1)returnitemsprint(bad_function())# [1]print(bad_function())# [1, 1] 不是预期的[1]# ✅ 正确做法使用None作为默认值defgood_function(itemsNone):ifitemsisNone:items[]# 每次调用创建新列表items.append(1)returnitemsprint(good_function())# [1]print(good_function())# [1] 正确在 IDEA 中编写代码时也会给出提示及修改后的代码。2、相等性比较Java 中 equals 判断内容是否相同判断是否是同一个对象。Python 中 判断值是否相同is 判断是不是同一个对象。【需注意别弄反了】# Python 陷阱2相等比较## Python的 和 is 区别## 判断值是否相等is判断是否是同一对象## Java中equals判断是否相等判断是否是同一对象a[1,2,3]b[1,2,3]caprint(ab)# True - 值相等print(aisb)# False - 不是同一对象print(aisc)# True - 同一对象## 小整数缓存类似Java Integer缓存## CPython的小整数缓存范围[-5, 256]x256y256print(xisy)# True - Python缓存小整数x257y257print(xisy)# True - (编译器优化同一代码块内的常量折叠)print(xy)# True - 值相等# 绕过编译器优化查看真实的内存行为x257yint(257)# 运行时生成不被缓存print(xisy)# False - 这证明了257确实不在小整数缓存[-5, 256]范围内3、循环变量作用域Python 中没有块级作用域编写代码时需注意。# Python陷阱3没有块级作用域funcs[]foriinrange(3):# lambda捕获的是变量i不是i的值funcs.append(lambda:print(fvalue:{i}))forfinfuncs:f()# 全部打印value: 2# 解决方案1使用默认参数funcs[]foriinrange(3):funcs.append(lambdaei:print(fvalue:{e}))forfinfuncs:f()# 解决方案2创建闭包funcs[]foriinrange(3):defmake_func(x):returnlambda:print(fvalue:{x})funcs.append(make_func(i))forfinfuncs:f()4、浅拷贝与深拷贝Python 中的浅拷贝、深拷贝与 Java 中的概念及含义类似。浅拷贝复制的是引用深拷贝是完全复制对象。特性浅拷贝 (copy)深拷贝 (deepcopy)外层对象创建新对象创建新对象内部元素引用原对象的元素递归复制原对象的元素速度快慢需要递归内存占用少多适用场景对象只有一层或希望共享内部状态对象有多层嵌套需要完全独立的数据副本Python 示例代码importcopy# 浅拷贝original[[1,2],[3,4]]shallow_copyoriginal.copy()original[0][0]100print(original)# [[100, 2], [3, 4]]print(shallow_copy)# [[100, 2], [3, 4]] 也被修改了# 深拷贝deep_copycopy.deepcopy(original)original[1][1]100print(original)# [[100, 2], [3, 100]]print(deep_copy)# [[100, 2], [3, 4]]八、实用工具对比下面是 Java 与 Python 中常用的工具/框架的对比Java工具/概念Python对应说明/差异构建工具Mavenpip pyproject.tomlPython使用pyproject.toml定义项目GradlePoetryPoetry是现代化的Python包管理工具测试框架JUnitpytestpytest功能更丰富语法更简洁Mockitounittest.mockPython内置mock模块日志记录Log4j/SLF4Jlogging模块Python标准库提供Web框架Spring BootFastAPI/Django/FlaskFastAPI适合APIDjango全功能JAX-RSFastAPI/FlaskORM框架HibernateSQLAlchemySQLAlchemy是Python的ORM标准JPADjango ORM/SQLAlchemy序列化Jackson/Gsonjson模块Python内置JSON支持函数式编程Stream API生成器/列表推导式Python使用yield创建生成器Optionaltyping.Optional类型提示非运行时检查文档生成Javadocdocstring SphinxPython使用reStructuredText或Google风格代码检查Checkstyle/PMDpylint/flake8Python有多种代码检查工具打包部署JAR/WARWheel/DockerPython使用wheel包分发九、Pythonic 编程风格Pythonic 指的是遵循 Python 哲学和习惯的编程风格强调简介、清晰、优雅、高效。直接在 python 命令中输入import this即可看到 Python 哲学。The Zen of Python, by Tim Peters 《Python 语言的核心哲学指南》 Beautiful is better than ugly. 代码美观性优先强调清晰、简介和一致性使代码易于理解和维护。 Explicit is better than implicit. 代码意图要明确表达以免晦涩的逻辑或魔法操作。比如明确引用模块而非通配符引入。 Simple is better than complex. 优选直接、简单的方案避免不必要的复杂性。比如使用列表推导式替代冗长的循环。 Complex is better than complicated. 如果问题本身很复杂代码应该有组织的处理复杂性而非杂乱无章。比如通过职责分离提升维护性。 Flat is better than nested. 减少代码嵌套越扁平越好使逻辑更清晰。比如提前返回简化条件嵌套。 Sparse is better than dense. 适当的代码间隔避免紧凑拥挤。比如合理使用空行和空格。 Readability counts. 可读性至关重要。比如使用描述性命名和文档字符串。 Special cases arent special enough to break the rules. 不要为特殊情况破坏代码一致性应在规则内统一处理。比如使用异常捕获而非特殊返回值。 Although practicality beats purity. 实用性优于纯粹性鼓励使用标准库避免重复造轮子。 Errors should never pass silently. 错误应该被明确处理避免静默忽略。比如精准捕获异常而非使用空的except块。 Unless explicitly silenced. 仅在明确需要时忽略错误或警告并指定作用范围和类型。 In the face of ambiguity, refuse the temptation to guess. 遇到不确定情况时应明确处理而非猜测。比如要求调用者指定数据格式。 There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless youre Dutch. 应该有一种且最好只有一种明显的方式来做这件事。不过除非你是荷兰人Python创始人否则一开始可能不那么明显。 Now is better than never. Although never is often better than *right* now. 现在开始比永远不做好。尽管“永远不做”常常比“立马匆忙去做”更好。 If the implementation is hard to explain, its a bad idea.If the implementation is easy to explain, it may be a good idea. 如果某个实现很难解释那它很可能是个坏主意。如果某个实现易于解释那它或许是个好主意。 Namespaces are one honking great idea -- lets do more of those! 命名空间是个绝妙的想法让我们多多使用它吧简单来说就是写出让人一眼就能看懂的代码、充分利用 Python 的特性、遵循社区约定和最佳实践、保持代码简介而不失去表达力。1. 列表推导式替代循环使用 Pythonic 的列表推导式替代传统的 Java 风格的循环。# Java风格非Pythoniclist[]foriinrange(10):ifi%20:list.append(i*2)print(list)# Pythonic风格list[i*2foriinrange(10)ifi%20]print(list)# 嵌套推导式matrix[[1,2,3],[4,5,6],[7,8,9]]flattened[numforrowinmatrixfornuminrow]print(flattened)2. 使用生成器节省内存生成器是惰性计算更加节省内存。可以计算一部分使用一部分有点像流式调用。# 1、列表推导式立即计算占用内容squares_list[x**2forxinrange(100000)]# 占用大量内存print(squares_list)# 2、生成器表达式惰性计算节省内存squares_gen(x**2forxinrange(100000))# 此时几乎不占内存只保存了计算规则## ⚠️ 注意调用 list() 会立即触发所有计算并将结果全部加载到内存中## 这会失去生成器节省内存的优势。## print(list(squares_gen))## ✅ 正确用法直接遍历用一个算一个内存占用极低类似于流式调用forvalinsquares_gen:# 这里演示只打印前几个避免刷屏ifval100:breakprint(val)# 3、生成器函数def定义的函数中包含yield关键字defread_large_file(file_path:str):逐行读取大文件# 只要函数里有 yield调用它就不会立刻执行而是返回一个生成器对象withopen(file_path,r,encodingutf-8)asfile:forlineinfile:# yield 相当于 return and pause (返回并暂停)# 1. 把值交出去# 2. 暂停函数执行记住当前状态比如读到第几行了# 3. 等待下一次被唤醒next()调用yieldline.strip()# 使用生成器函数# 调用 read_large_file 时并没有开始读文件只是拿到了一个生成器forlineinread_large_file(file_pathlarge_file.txt):# 每次循环生成器恢复执行直到遇到下一个 yieldprint(line)3. 上下文管理器替代try-finallyJava 中有 try-with-resource 实现资源的自动关闭。Python 中也有上下文管理器支持对资源进行获取及关闭。# Java风格资源管理 try-with-resources# try (BufferedReader br new BufferedReader(new FileReader(file.txt))) {# // 使用资源# }# Python上下文管理器自动初始化和关闭资源# with open(large_file.txt, r, encodingutf-8) as file:# content file.read()# print(content)# 自定义上下文管理器fromcontextlibimportcontextmanager# 模拟资源获取函数defacquire_resource(name):print(f资源 {name} 已获取)returnname# 模拟资源释放函数defrelease_resource(resource):print(f资源 {resource} 已释放)contextmanagerdefmanaged_resource(*args,**kwargs):# 初始化资源resourceacquire_resource(*args,**kwargs)try:# yield 前面是 __enter__ 逻辑yieldresourcefinally:# yield 后面是 __exit__ 逻辑finally 确保即使报错也会执行release_resource(resource)# 测试代码if__name____main__:print(\n--- 自定义上下文管理器演示 ---)withmanaged_resource(TestDB)asdb:print(f正在使用:{db})print(Doing work...)4. 使用枚举EnumJava 中有枚举类。Python 同样支持枚举类。# 从 enum 模块中导入 Enum 类auto是一个辅助函数用于自动分配枚举值fromenumimportEnum,auto# 定义枚举classColor(Enum):# auto() 会自动分配值默认从 1 开始递增 (1, 2, 3...)# 当你不关心具体的值只关心唯一性时非常有用REDauto()GREENauto()YELLOWauto()# 使用枚举defprocess_color(color:Color):ifcolorColor.RED:print(Stop)elifcolorColor.GREEN:print(Go)elifcolorColor.YELLOW:print(Caution)else:raiseValueError(fInvalid color:{color})process_color(Color.GREEN)# 遍历枚举forcolorinColor:print(f{color.name}:{color.value})十、wheel pyproject.toml 案例工具概述 pyproject.toml 是 Python 社区为了统一构建配置而推出的标准配置文件。用于替代散乱的setup.py、requirements.txt、setup.cfg、MANIFEST.ini等文件。 wheel 是 Python 的二进制分发格式包含预编译的扩展模块如 C/C扩展编码用户安装时需要本地编辑器如 gcc 或 Visual Studio。1️⃣ 设计目标快速、可靠的安装避免在目标机器上编译代码。2️⃣ 支持跨平台兼容Win、MacOS、Linux每个 wheel 包都会有一个标签说明是哪一个平台的。pip 安装时会自动选择与当前环境匹配的 wheel 安装无需源码编译。示例numpy-1.24.0-cp39-cp39-win_amd64.whl解读cp39-cp39 表示适用于 CPython 3.9win_amd64 表示适用的平台。3️⃣ 为什么 wheel 比源码包更好特性源码包**font stylecolor:rgb(15, 17, 21);.tar.gz/font**Wheel 包**font stylecolor:rgb(15, 17, 21);.whl/font**安装速度较慢可能需要编译极快直接解压文件到 site-packages依赖编译器是如果有 C 扩展否跨平台可靠性依赖本地环境高预编译针对特定平台元数据需执行font stylecolor:rgb(15, 17, 21);setup.py/font读取包含在font stylecolor:rgb(15, 17, 21);.dist-info//font中可直接读取4️⃣ 如何使用pip 安装是会自动选择 wheel方式 1从 PyPI 安装pip install 包名方式 2本地 wheel 文件pip install 路径/xxx.whl方式 3强制使用源码包pip install --no-binary 包名案例下面创建一个非常简单 wheel pyproject.toml 的案例。目录结构如下编写 pyproject.toml 文件# 定义构建工具 [build-system] requires [setuptools61.0, wheel] build-backend setuptools.build_meta # 定义项目元数据 [project] name my-math-lib version 0.1.0 description 一个极简的数学计算包示例 readme README.md requires-python 3.8 authors [ {name DemoUser, email demoexample.com} ]编写 my_math.pydefadd(a,b):returnabdefsub(a,b):returna-bif__name____main__:print(f1 1 {add(1,1)})编写 README.md在pyproject.toml中使用readme README.md指定了 readme 文件。# My Math Lib 这是一个用于演示 Wheel 打包的示例项目。构建 Wheel 包在wheel_demo目录下运行以下命令。1、安装构建工具pipinstallbuild# Collecting build# Downloading build-1.3.0-py3-none-any.whl.metadata (5.6 kB)# Collecting packaging19.1 (from build)# Downloading packaging-25.0-py3-none-any.whl.metadata (3.3 kB)# Collecting pyproject_hooks (from build)# Downloading pyproject_hooks-1.2.0-py3-none-any.whl.metadata (1.3 kB)# Requirement already satisfied: colorama in d:\idea-workspace-python\helloworld\.venv\lib\site-packages (from build) (0.4.6)# Downloading build-1.3.0-py3-none-any.whl (23 kB)# Downloading packaging-25.0-py3-none-any.whl (66 kB)# Downloading pyproject_hooks-1.2.0-py3-none-any.whl (10 kB)# Installing collected packages: pyproject_hooks, packaging, build# Successfully installed build-1.3.0 packaging-25.0 pyproject_hooks-1.2.2、开始构建python -m build3、查看结果构建后会在当前目录下产生一个 dist 目录里面就是打好的包。至此Java 转换 Python 介绍完毕 只有一步一步代码敲过来才能领会 Python 语言的魅力。参考1.https://docs.python.org/zh-cn/3.13/tutorial/index.html

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询