199 lines
4.0 KiB
Markdown
199 lines
4.0 KiB
Markdown
# aTools 兼容性说明
|
|
|
|
## ✅ 支持的 Maya 版本
|
|
|
|
- **Maya 2017-2020**: Python 2.7
|
|
- **Maya 2022+**: Python 3.7+
|
|
- **Maya 2023+**: Python 3.9+
|
|
- **Maya 2025+**: Python 3.11+
|
|
|
|
## 🔧 兼容性修复
|
|
|
|
### 1. Python 2/3 兼容性 ✅
|
|
|
|
#### 字符串格式化
|
|
- ❌ **避免使用**: f-string (Python 3.6+)
|
|
```python
|
|
# 错误
|
|
print(f"backup: {bkpFolder}")
|
|
```
|
|
- ✅ **推荐使用**: `.format()` 或 `%` 格式化
|
|
```python
|
|
# 正确
|
|
print("backup: {}".format(bkpFolder))
|
|
print("backup: %s" % bkpFolder)
|
|
```
|
|
|
|
#### 已修复的文件
|
|
- `animationCrashRecovery.py` - 第 297 行 f-string 已修复
|
|
|
|
### 2. NoneType 错误防护 ✅
|
|
|
|
#### 列表/字典访问前检查
|
|
```python
|
|
# 错误 - 可能导致 TypeError
|
|
data = some_function()
|
|
value = data[0] # 如果 data 是 None 会崩溃
|
|
|
|
# 正确 - 添加检查
|
|
data = some_function()
|
|
if data and len(data) > 0:
|
|
value = data[0]
|
|
else:
|
|
value = default_value
|
|
```
|
|
|
|
#### 已修复的文件
|
|
- `setup.py` - 第 63 行添加长度检查
|
|
- `animationCrashRecovery.py` - 第 331, 336 行添加 None 检查
|
|
- `generalToolsUI.py` - 第 50 行添加 None 检查
|
|
|
|
### 3. 文件路径处理 ✅
|
|
|
|
#### 使用 os.path 而非硬编码
|
|
```python
|
|
# 错误
|
|
path = "C:\\Users\\..."
|
|
|
|
# 正确
|
|
import os
|
|
path = os.path.join(base_dir, "subfolder", "file.txt")
|
|
```
|
|
|
|
#### 路径分隔符
|
|
```python
|
|
# 使用 os.sep 而非 \\ 或 /
|
|
folder = base_path + os.sep + subfolder
|
|
# 或更好的方式
|
|
folder = os.path.join(base_path, subfolder)
|
|
```
|
|
|
|
### 4. 导入兼容性 ✅
|
|
|
|
#### 相对导入
|
|
所有内部导入已改为相对导入:
|
|
```python
|
|
# 之前
|
|
from aTools.commonMods import animMod
|
|
|
|
# 现在
|
|
from commonMods import animMod
|
|
```
|
|
|
|
### 5. Maya API 兼容性
|
|
|
|
#### cmds vs pymel
|
|
- 优先使用 `maya.cmds` (更稳定)
|
|
- 避免依赖 `pymel` (可选依赖)
|
|
|
|
#### API 版本检查
|
|
```python
|
|
import maya.cmds as cmds
|
|
|
|
maya_version = int(cmds.about(version=True))
|
|
if maya_version >= 2022:
|
|
# Python 3 特性
|
|
pass
|
|
else:
|
|
# Python 2 兼容代码
|
|
pass
|
|
```
|
|
|
|
## 🛡️ 错误处理最佳实践
|
|
|
|
### 1. 文件读取
|
|
```python
|
|
try:
|
|
with open(filepath, 'r') as f:
|
|
content = f.read()
|
|
except IOError:
|
|
content = None
|
|
print("Failed to read file: {}".format(filepath))
|
|
|
|
if content:
|
|
# 处理内容
|
|
pass
|
|
```
|
|
|
|
### 2. 列表访问
|
|
```python
|
|
def safe_get(lst, index, default=None):
|
|
"""安全获取列表元素"""
|
|
try:
|
|
return lst[index] if lst and len(lst) > index else default
|
|
except (IndexError, TypeError):
|
|
return default
|
|
|
|
# 使用
|
|
value = safe_get(data, 0, "default_value")
|
|
```
|
|
|
|
### 3. 字典访问
|
|
```python
|
|
# 使用 get() 方法
|
|
value = my_dict.get('key', default_value)
|
|
|
|
# 而不是
|
|
value = my_dict['key'] # 可能 KeyError
|
|
```
|
|
|
|
## 📋 兼容性检查清单
|
|
|
|
### 代码检查
|
|
- [x] 无 f-string
|
|
- [x] 无 Python 3 专有语法
|
|
- [x] 所有列表/字典访问有 None 检查
|
|
- [x] 文件路径使用 os.path
|
|
- [x] 导入语句正确
|
|
|
|
### 测试检查
|
|
- [ ] Maya 2017 (Python 2.7)
|
|
- [ ] Maya 2020 (Python 2.7)
|
|
- [ ] Maya 2022 (Python 3.7)
|
|
- [ ] Maya 2023 (Python 3.9)
|
|
- [ ] Maya 2024 (Python 3.10)
|
|
- [ ] Maya 2025 (Python 3.11)
|
|
|
|
### 功能检查
|
|
- [ ] 模块导入成功
|
|
- [ ] UI 启动正常
|
|
- [ ] 所有工具可用
|
|
- [ ] 无错误/警告
|
|
|
|
## 🔍 自动检查工具
|
|
|
|
运行兼容性检查脚本:
|
|
```python
|
|
# 在 atools 目录下
|
|
python check_compatibility.py
|
|
```
|
|
|
|
## 📝 已知限制
|
|
|
|
1. **Python 2.7 支持**:
|
|
- Maya 2017-2020 使用 Python 2.7
|
|
- 必须避免 Python 3 专有特性
|
|
|
|
2. **Maya API 变化**:
|
|
- 某些 API 在不同版本有变化
|
|
- 使用 try-except 处理版本差异
|
|
|
|
3. **第三方依赖**:
|
|
- 尽量减少外部依赖
|
|
- 如需依赖,确保跨版本兼容
|
|
|
|
## 🚀 最佳实践总结
|
|
|
|
1. ✅ 使用 `.format()` 而非 f-string
|
|
2. ✅ 所有数据访问前检查 None
|
|
3. ✅ 使用 `os.path` 处理路径
|
|
4. ✅ 添加 try-except 错误处理
|
|
5. ✅ 测试多个 Maya 版本
|
|
6. ✅ 保持代码简洁清晰
|
|
7. ✅ 添加详细注释和文档
|
|
|
|
---
|
|
|
|
**最后更新**: 2025-11-25
|
|
**状态**: ✅ 兼容性修复完成
|