PY官网
https://www.python.org/downloads/
一. 简介
| 阶段 | Python(CPython 常见流程) | C#(.NET/CLR/Mono:JIT 路线) | C#(Unity:IL2CPP 路线,偏 AOT) | 产物/缓存 | 常见失败点 |
|---|---|---|---|---|---|
| 1. 写代码 | 写 .py 源码 |
写 .cs 源码 |
写 .cs 源码 |
源文件 | 语法错误(两者都有) |
| 2. 依赖/环境准备 | 创建 venv、pip install 依赖;依赖在运行时加载 |
还原 NuGet 包;依赖在编译/运行时由 CLR 解析 | Unity Package/asmdef/插件;原生库随平台配置 | Python:site-packages;C#:NuGet 缓存/Packages |
版本冲突、路径/环境变量、缺包 |
| 3. 语法解析 | 解释器读 .py,词法/语法分析 生成 AST |
编译器 Roslyn 读 .cs,词法/语法分析 生成语法树 |
同左 | 中间表示(AST/语法树) | Python:缩进/语法;C#:语法/项目引用 |
| 4. 语义检查/类型检查 | 动态类型:只做基本语义检查;多数类型问题推迟到运行时 | 静态类型:编译期做类型/泛型/重载/可访问性检查 | 同左,但 Unity 还会加一套平台/剥离相关约束 | 编译诊断信息 | C#:编译报错更早暴露;Python:很多错运行才爆 |
| 5. "编译"阶段 | CPython 把 AST 编译成字节码 (可能生成/更新 .pyc) |
编译器把源码 编译成 IL + 元数据,生成程序集 .dll/.exe |
先同左生成 IL(Unity 的 Assembly) | Python:.pyc;C#:.dll/.exe |
Python:字节码生成失败少见;C#:链接引用、条件编译、asmdef 问题 |
| 6. 装载(Load) | Python 解释器启动,按 import 规则加载模块、执行顶层代码 |
CLR/Mono 装载程序集,解析依赖,准备类型信息 | Unity 装载 IL 程序集,准备后续 IL2CPP 转换 | 内存中的模块/程序集 | Python:import 循环/路径;C#:Assembly 绑定失败 |
| 7. 运行前准备 | 解释器创建运行时对象模型(模块、函数对象等) | JIT 按需准备方法:首次调用某方法时可能触发 JIT | IL2CPP 在构建期把 IL 转 C++,运行时无需 JIT(主要是初始化/装载) | 运行时元数据 | Unity:IL2CPP 构建配置/平台 SDK 问题 |
| 8. 执行方式(关键差异) | 解释器虚拟机执行字节码(逐条 dispatch),对象模型动态查找 | JIT 把热点方法编译为机器码,CPU 直接跑机器码;冷门方法按需编译 | AOT:IL → C++ → 原生机器码(构建时完成),CPU 直接跑 | JIT 缓存/原生可执行 | 性能差异主要来自这里:解释执行 vs 机器码执行 |
| 9. 运行时内存管理 | CPython:引用计数为主 + 循环 GC | GC(分代回收),对象生命周期由 GC 决定 | 同左(Unity/Mono/IL2CPP 的 GC 细节略有不同) | 堆、GC 状态 | Python:循环引用导致延迟释放;C#:GC 抖动(大量分配) |
| 10. 异常/报错时机 | 很多错误(类型、属性不存在等)在 运行到那行 才抛异常 | 很多错误(类型不匹配等)在 编译期 已报;运行期多为逻辑/NullReference 等 | 同左,另有 AOT/裁剪导致的反射/泛型缺失问题 | traceback / stacktrace | Unity IL2CPP:反射/泛型/链接裁剪坑较多 |
| 11. 发布/交付 | 交付源码 + 依赖(或打包成可执行/zip/容器);运行环境要有解释器 | 交付程序集 + runtime(或自包含发布),目标机有 .NET/Mono | Unity 生成平台原生包(exe/app/apk/ipa),含 IL2CPP 产物 | 可执行/安装包 | Python:依赖环境不一致;C#:平台差异/原生库 |
| 12. 启动速度与迭代体验 | 启动快、改完即跑(脚本友好) | 编译需要时间,但运行后性能好;首次调用可能 JIT 抖动 | 构建时间更长(转 C++/编译),但运行更稳定 | 构建缓存 | Python:迭代最快;Unity IL2CPP:构建最慢但交付最好 |
-
解释型语言逐行,编译型直接执行编译后的机器码。
-
解释型编写代码时候只会进行基础检查,编译型语言在编写和编译为中间语言和AOT前就将大多数问题检查出来。
-
声明变量不需要类型。
二. 运算
/ 是得到float。 // 结果向下取整。
17 / 3 # 经典除法运算返回一个浮点数
5.666666666666667
17 // 3 # 向下取整除法运算会丢弃小数部分
5
**代表乘方
5 ** 2 # 5 的平方
25
2 ** 7 # 2 的 7 次方
128
三. 转义与字符串
"AAA"等与'AAA'
如果要将引号作为字符串
"\"斜杠符号"
如果不希望前置 \ 的字符转义成特殊字符,可以使用 原始字符串 ,在引号前添加 r 即可:
print(r'C:\some\name') # 请注意引号前的 r
C:\some\name
使用"""..."""可以跨越多行:
>>>print("""\
...Usage: thingy [OPTIONS]
... -h Display this usage message
... -H hostname Hostname to connect to
... """)
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
字符串下标访问和字串:
python
name = 'python'
print(name[0])
print(name[-1])
print(name[0:2])
len(name)
# p
# n
# py
# 6

四、PY的列表和C#的数据结构
| Python 数据结构 | 典型写法 | C# 最接近的结构 | 是否可变 | 元素类型约束 | 查找/访问特性(常见) | 典型用途(对 Unity/引擎脚本) |
|---|---|---|---|---|---|---|
list |
a = [1,2,3] / a.append(x) |
List<T>(语义)/ T[](连续内存感)/ List<object>(混类型时) |
✅ 可变 | ❌ 无(可混类型) | 索引 O(1),in 查找 O(n),末尾追加均摊 O(1),中间插入/删除 O(n) |
有序集合、队列式收集、遍历处理、批量数据(资源列表、实体列表) |
tuple |
t = (1,"a") |
ValueTuple<> / 不可变数组的概念 |
❌ 不可变 | ❌ 无(可混类型) | 索引 O(1);不可修改 | 返回多个值、当作轻量"记录"、用作 dict 的 key(如果内容都可哈希) |
dict |
d={"id":1} / d[k]=v |
Dictionary<TKey,TValue> |
✅ 可变 | ❌ 无(key/value 可混类型,但不建议) | key 查找/插入均摊 O(1);保持插入顺序(新版本 Python) | 映射/索引(id→对象)、配置表、JSON 数据、快速查找 |
set |
s={1,2,3} / s.add(x) |
HashSet<T> |
✅ 可变 | ❌ 无(元素可混类型但需可哈希) | in 查找均摊 O(1);不保证排序(迭代顺序不是"排序"概念) |
去重、集合运算(交并差)、快速 membership 判断 |
str |
"abc" |
string |
❌ 不可变 | N/A | 索引 O(1)(按字符视角),拼接频繁会有开销(Python 建议用 ''.join(...)) |
文本、路径、日志、序列化 |
bytes |
b = b"\x01\x02" |
byte[](最接近) |
❌ 不可变 | N/A | 二进制序列;适合 I/O | 文件/网络二进制、序列化结果 |
bytearray |
ba = bytearray(b"...") |
List<byte> / 可变 byte[] 的用法 |
✅ 可变 | N/A | 可原地修改 | 需要改写的二进制缓冲区 |
range |
range(10) |
Enumerable.Range(0,10) |
❌(生成器式) | N/A | 懒生成,不会一次性建完整 list | for 循环计数,避免创建大数组 |
collections.deque |
deque([1,2]) |
Queue<T> / LinkedList<T>(语义) |
✅ 可变 | (同样无静态约束) | 两端 push/pop O(1) | 队列/双端队列(BFS、任务队列) |
list + "当栈用" |
a.append(x); a.pop() |
Stack<T>(语义) |
✅ 可变 | ❌ 无 | push/pop 均摊 O(1) | 临时栈、回溯、解析 |
dict + "计数器" |
Counter(a) |
Dictionary<T,int> |
✅ 可变 | ❌ 无 | 计数聚合 | 统计日志、频次、TopN |
五、 一个编程小案例
斐波那契数列
a, b = 0,1 while a< 10 : print(a) a,b = b,a+b