前言

  前段时间写代码,测试 maya 工具,总是突然之间发现信息输出到了 Output Window
  但是也不知道是什么原因造成的。
  因为使用的环境和工具很多,不知道是哪一个东西导致的,一直没有查出来。
  最近我很偶然地定位到问题所在的工具,于是去查了一下这个问题出在哪里。

问题根源

  经过代码测试之后,我发现是某个历史脚本里面加了一行 reload(sys) 的代码导致的。
  只要在 Maya 环境下执行 reload(sys)
  那么输出就到了 Output Window 上了。

原因探讨

  其实通过之前 焕唤 做 AppMananger 工具同步学到了 print 的操作是可以 override 的。
  print 背后调用的其实是 sys.stdout.write 的函数。
  如果将 sys.stdout 覆盖为一个新的 类 对象,并且同样提供 write 的方法。
  就可以将打印的操作变成我们自定义的操作。
  AppMananger 复写为了输出 log

  同理,Maya 默认是输出到 Output Window 里的。
  通过查 Maya Python 库 maya.app.startup.gui 脚本里面可以找到相应的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# module: maya.app.gui
#
# This module is imported during the startup of Maya in GUI mode.
#
import sys
import maya.app.startup.basic

# Run the user's userSetup.py if it exists
maya.app.startup.basic.executeUserSetup()

import maya.app.baseUI
import maya.utils

# Replace sys.stdin with a GUI version that will request input from the user
sys.stdin = maya.app.baseUI.StandardInput()

# Replace sys.stdout and sys.stderr with versions that can output to Maya's
# GUI
sys.stdout = maya.utils.Output()
sys.stderr = maya.utils.Output( error=1 )

maya.utils.guiLogHandler()

# ADSK_CLR_MGT_BEGIN
import maya.app.colorMgt.customTransformUI
import maya.app.colorMgt.inputSpaceRulesUI
# ADSK_CLR_MGT_END

import maya.app.quickRig.quickRigUI
# ===========================================================================
# Copyright 2018 Autodesk, Inc. All rights reserved.
#
# Use of this software is subject to the terms of the Autodesk license
# agreement provided at the time of installation or download, or which
# otherwise accompanies this software in either electronic or hard copy form.
# ===========================================================================

  reload(sys) 操作会将这些覆盖的函数重新用回了 Python 的默认操作。
  所以才会导致 print 打印输出到了 Output Window 上。

  另外这里 maya.utils.Output 这个类应该是从 C++ 里面创建出来的。
  在 utils.py 里面并没有定义,并且 utils.py 也有说明,部分的方法诸如 executeInMainThreadWithResult 是来自 C++ 的

总结

  reload(sys) 的使用场景是想使用 sys.setdefaultencoding(‘utf-8’) 解决 Python2 蛋疼的 encoding 问题。
  然而实际使用情况下很复杂,这个操作并不能彻底解决问题,所以 python2 环境最好就规避中文,避免字符处理问题。

1
2
3
4
5
6
7
# NOTE 修复中问报错提示问题
reload(sys)
sys.setdefaultencoding("utf-8")
# NOTE reload sys 会导致 Maya 无法将信息输出到脚本编辑器
sys.stdin = maya.app.baseUI.StandardInput()
sys.stdout = maya.utils.Output()
sys.stderr = maya.utils.Output(error=1)