背景
笔者作为 Java 服务端开发的从业者, 因公司内部需要, 开始转 Python 服务端项目建设, 借此契机从自身的角度出发, 对比看待 Python 这门语言他的特点和一些开发心得, 为后续的其他有相关转 Python 的同学提供经验, 让大家都能够快速上手这门语言进入开发状态.
面向群体
- 有基础服务端开发经验, 但无 Python 开发经验的同学
Java Vs Python
为了让大家快速理解 Python 这门语言, 笔者帮大家总结一份 Java 和 Python 的特点对比, 让大家先从宏观角度去理解 Python 的特点是什么
看到这个后, 笔者理解 Python 的特点是 弱类型检查, 强大的三方库, 尤其是 AI 和数据, 写一个 hello world 门槛低
对比项 | Java | Python |
---|---|---|
类型安全 | 静态类型(需要显式声明类型) | 动态类型 |
编译方式 | 编译成字节码,通过JVM执行 | 解释型,但也可以编译成字节码或本地代码(大部分先编译成 Cython, 再转字节码) |
性能 | 通常比Python快,特别是计算密集型任务 | 通常比Java慢,但有JIT和C扩展优化 |
语法 | 更为冗长 | 简洁,易于阅读 |
应用领域 | 企业应用、Android开发、大型系统等 | Web开发、数据分析、AI、脚本等 |
生态系统和库 | 丰富的标准库和开源生态系统 | 丰富的标准库,以及强大的第三方库(如NumPy) |
平台独立性 | 通过JVM,具有较好的跨平台性 | 通过解释器,也有跨平台特性 |
社区支持 | 庞大的开发者社区和企业支持 | 广泛的社区支持,特别是在AI和数据领域 |
学习难度 | 相对较高,特别是对于初学者 | 较为简单,常被视为初学者的入门语言 |
并发处理 | 通过线程,有复杂的并发API | 有GIL限制(可以控制),但可以使用多进程、异步IO等方法 |
开发工具 | Eclipse, IntelliJ IDEA, NetBeans等 | PyCharm, VSCode, Jupyter等 |
Python 开发环境选择
如果是一些比较简单的 Python 项目, 大家可以就自己的系统安装 Python 环境即可, 这里笔者是因为要做实际服务端项目开发, 因此将自己遇到的一些实际问题和大家分享一下
基础要求
- 电脑一台, 可以用于本地编写项目, 用于 Python 环境安装以及开发工具安装等
Python 系统环境&工具选择
Python 的开发工具, 主流的还是两种, VsCode(轻 IDE 模式) 和 PyCharm(重 IDE 模式)
服务端开发不适合使用 windows 系统进行开发
- 项目中可能有一些 py 库只支持 linux 或者 macos x86 芯片, 因此 Windows 或者 macos M1 环境下是可能无法本地运行
- 对服务端项目开发来说, 几乎所有生产环境部署在 Linux 环境中的, 因此也尽量能保证自己的开发环境和真实的部署环境是一致的, 事后复现问题会比较有帮助
Python 解释器 & Python 虚拟环境 介绍
此处的理解仅为笔者当前状态下的自我理解, 有可能和官方的设计存在理解偏差, 但仅适用于此篇文章中, 对入门学习 Python 做个指引
Python 的解释器 是 类似与 Java JVM 的一样的存在, 去支持 Python 代码的读取和执行, 通过不同实现的解释器去完成对跨平台的适配.
Python 虚拟环境 是 基于 安装 Python 环境的基础上, 为项目创建的独立&隔离的 Python 运行环境, 在此环境中, 安装一些项目依赖库 不会污染我们 系统 Python 环境, 能够保证多项目开发时, 各项目环境的独立性也便于移植, 这是目前 Python 开发的一种最佳实践
Python 开发模式选择
开发模式 | 系统环境 | 运行环境 | 解释器 |
---|---|---|---|
本地开发 & 本地调试 | Macos/Ubuntu 可视化 | Macos/Ubuntu 可视化 | 本地虚拟环境 |
本地开发 & 远程调试 | 均可 | Ubuntu(虚机或者远程服务器) | SSH 远程虚拟环境 |
本地开发 & 远程部署 | 均可 | Ubuntu(虚机或者远程服务器) | SSH 远程部署 |
关于上述模式的各项安装细节, 大家可以自行按照自己的实际电脑环境搜索网上的安装要求, 这里就不多做介绍了
综合上述, 结合自己的电脑环境可以自行选择使用哪种开发模式, 推荐本地开发&调试, 可以 debug 代码 方便问题排查.
Python 入门
Python hello world
bash
# 创建一个 python 的工作项目目录
mkdir demo
# 进入工作项目目录
cd demo
# 初始化虚拟环境
python -m venv .venv
# 启用虚拟环境
source .venv/bin/activate
# 创建一个 demo.py 文件 并写入 python 代码
touch demo.py && echo 'print("hello world")' > demo.py
# 运行这个文件
python demo.py
hello world
笔者用终端完成了 Python hello world 的撰写, 如此简单的运行门槛瞬间让笔者想到了 Java hello world 是多么的麻烦, 也想到了 jdk 这么多年的新特性多多少少都有点其他优秀编程语言的影子...
新的巨人总是站在新的巨人之上的..
从这个例子也可以看到, python 运行需要指定一个入口文件, 但这个文件不需要用到 class 或者方法, 由此可以看出一旦调用某个 py, 就一定会从上到下执行.
如果从面向对象开发来说, 则就是 定义一个 class 再定义一些方法, 最后初始化这个class 再调用即可
python
class Person:
def __init__(self, name:str):
self._name = name
@staticmethod
def desc():
print("我是人类")
def run(self):
print(f"你好: 我是 {self._name}")
Person.desc()
_me_is_sky = Person("Python rookie Sky")
_me_is_sky.run()
从基于上述代码,我们可以从中总结出以下Python的编程风格和特点:
- 命名约定:
-
- 使用
snake_case
(如_me_is_sky
)命名变量和函数。 - 使用
CamelCase
命名类(如Person
)。 - 使用一个下划线前缀(如
_name
)表示受保护的实例变量,这是一种约定,意味着这些变量不应该从类外部直接访问,但它们实际上可以被访问(不同于其他语言中的"私有"修饰符)。
- 使用
- 函数和方法注解:
-
- 使用类型注解来指定期望的参数类型(如
name:str
)。这增加了代码的可读性和文档性,并可以与工具(如mypy
)结合,进行静态类型检查。
- 使用类型注解来指定期望的参数类型(如
- 文档字符串 (在上述代码中未提及,但是是Python的常见特点):
-
- 使用三引号(
"""
)为函数、类和方法提供文档字符串。这为函数的用途、参数和返回值提供了描述,并可以被各种文档工具读取。
- 使用三引号(
- 装饰器:
-
- 使用
@staticmethod
装饰器来定义静态方法。装饰器是Python中扩展和修改函数或方法行为的一种方式。
- 使用
- 字符串格式化:
-
- 使用f-string(如
f"你好: 我是 {self._name}"
)进行字符串格式化,这是Python 3.6及以后版本的新特性,提供了一种简洁且可读的方式来插入变量和表达式到字符串中。
- 使用f-string(如
- 清晰的结构:
-
- Python使用缩进(而不是大括号)来表示代码块,如类和函数体。这强调了代码的可读性,并强制程序员维护整洁的代码结构。
- 简洁的方法定义:
-
- 使用
def
关键字定义函数和方法,提供了一种简洁的方式来声明代码块。
- 使用
总的来说,Python的风格特点强调代码的可读性、简洁性和明确性。这使得Python代码很容易理解,即使是对于那些不太熟悉Python语言的人。
Python Web 项目实战
笔者的开发模式为 本地开发 & 本地调试 : 工具为 Macbook M1 Pro + Pycharm + 本地虚拟环境
Python 的 web 框架众多,以下是一些较为流行和常用的框架:
- Django:一个高级的 Python Web 框架,它鼓励快速开发并遵循清晰的 MVC 设计。Django 提供了许多内置功能,例如一个后台管理系统、认证等。
- Flask:一个轻量级的 Web 框架,适合于小型应用和微服务。Flask 提供了基础的路由机制和模板引擎,但不包含像 Django 那样的预先构建的功能。
- FastAPI:一个现代的、快速(高性能)的 web 框架,用于构建 APIs。它基于标准 Python 类型提示。
- Tornado:一个用于 Web 应用程序的可扩展、非阻塞 Web 服务器和 Web 框架。Tornado 常用于需要长连接的应用,例如 WebSockets。
- Bottle:一个单文件、轻量级的 micro web 框架。适用于小型应用。
- Pyramid:一个灵活的小型框架,适用于大型和小型应用。与 Django 和 Flask 不同,Pyramid 在许多方面都采用"插件"方式,允许开发者选择需要的组件。
- CherryPy:一个对象导向的 web 框架,使用 Python 编写。它使得 web 开发变得像编写 Python 对象一样简单。
- Web2py:无需配置和安装即可运行的全栈框架,带有 web 服务器、数据库等。
- TurboGears:一个全栈框架,结合了多个主要的 Python 库。
- Falcon:用于构建高性能 API 的微型框架。
以上只是其中一些流行的框架。根据项目的需求和规模,以及你对某个框架的熟悉程度,可以选择适合的框架。
Python FastAPI Hello world
笔者公司内部采用的项目是 FastAPI 作为 Web 框架, 因此接下来笔者将实操项目搭建和代码分享, 帮助大家快速搭建 Demo
通过 Pycharm 新建项目, 我们可以快速搭建一个 FastAPI 的项目模型
点击创建后, 我们可以看到项目已经帮我们初始化好了
python
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/hello/{name}")
async def say_hello(name: str):
return {"message": f"Hello {name}"}
玩过 idea 的都知道, 点击右上角的运行的小图标, 我们就可以启动项目了
vbnet
/Users/sky/develop/python/fastApiDemo/.venv/bin/python /Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/pydevd.py --module --multiprocess --qt-support=auto --client 127.0.0.1 --port 64109 --file uvicorn main:app --reload
已连接到 pydev 调试器(内部版本号 232.10072.31)INFO: Will watch for changes in these directories: ['/Users/sky/develop/python/fastApiDemo']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [11244] using WatchFiles
INFO: Started server process [11246]
INFO: Waiting for application startup.
INFO: Application startup complete.
或者 我们在项目 home 目录下面执行启动命令
uvicorn 类似于 java tomcat 这种服务容器
vbnet
python -m uvicorn main:app
INFO: Started server process [11449]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
访问 http://127.0.0.1:8000, 我们就可以访问到服务的API 了
json
{
"message": "Hello World"
}
从这些步骤走下来, 其实 Python Web 的项目搭建其实不难, 在这个过程中, 大量借助了 ide 的自动化帮我们做好了架子, 但实际开发过程中, 我们必然少不了一些基础的组件功能, 例如 鉴权 数据库操作 等等, 所以 hello world 好写, 难写的是如何把它作为一个公司生产可用的项目.
Web 项目 Python 基础组件支持
这里的基础组件来源于
- 笔者对 Java Web 项目搭建总结出来的一些基础通用组件
- 项目组中 资深 Python 专家对已有生产项目的应用实践
如果公司有成熟的项目框架, 那这些都应该概括其中, 否则你可以给框架设计的同事提需求或者 PR 了, 因为笔者也是新手, 所以就没法给大家贴代码啦
代码质量
依赖管理 pyproject.toml
- 管理项目中使用的三方依赖, 便于快速初始化新环境
静态校验 mypy
- 提高项目代码质量, 解决后期维护成本
部署提交
CI & CD
- 项目自动构建&打包&部署, 提高工作效率
多环境支持
- 项目多环境部署时, 环境变量配置区分
问题追踪
异常统一 & 拦截
- 服务端业务异常和服务异常的标准化定义, 以及全局异常拦截, 确保底层异常不暴露给用户
日志统一格式化
- 提高项目输出可读性, 便于排查问题
链路追踪 contextvars
- 问题排查时, 基于 链路 ID 索引查找所有相关日志
业务推进
鉴权体系
- 用于对外项目通用鉴权拦截设计
数据库操作
- 数据库操作 Mixin 封装, 用于 service 层 通用 CRUD 操作
API 返回模型标准化
- 服务端返回数据的标准化, 便于前端对接
总结
- 写 Python 习惯了, 再写 Java 代码 就感觉有 Gap 了
-
- 方法参数默认值 vs 方法重载
- if (condition) {} vs if condition :
- **kwargs
彩蛋
- 你能看出来哪些是由 AI 生成的吗