我有一个应用程序,我想在条件发生时覆盖某些函数,例如:
condition_check.py:
Flag = True
import ctypes # An included library with Python install.
import inspect
def MsgBox(msg):
ctypes.windll.user32.MessageBoxA(0, msg, 'MsgBox', 1)
def check():
global print
if Flag:
def print(msg):
MsgBox(msg)
else:
pass
main.py:
## works
from condition_check import *
MsgBox('this is msgbox')
print('this is a print')
## does not work
import condition_check
condition_check.MsgBox('this is msgbox')
print('this is a print')
我了解condition_check.py
覆盖了自己的print
而不是main.py
的{{1}}。我相信 inspect 库可用于此目的,但我无法查找示例。
答案 0 :(得分:2)
我假设您使用的是Python 3.如果您使用Python,则只需设置内置模块的属性。
import builtins
import ctypes
original = builtins.print
Flag = True
def MsgBox(msg):
ctypes.windll.user32.MessageBoxA(0, msg, 'MsgBox', 1)
def check():
if Flag:
builtins.print = MsgBox
else:
builtins.print = original
但是,我会注意到一些事情:
Flag
由于两个原因而不是一个好名字: 1 ,它不具备任何描述性。标志仅表示它是True
或False
;它没有说明它的用途。 2 ,Python的官方风格指南(PEP 8)建议使用snake_case,而不是常规变量的PascalCase。 PascalCase只能用于类。
PEP 8不推荐使用通配符导入(from <module> import *
),因为它们不清楚命名空间中存在哪些名称,这会使读取器和自动化工具混淆。 (几乎是Imports部分的准确引用。)
您不需要覆盖print
功能。更好的方法是将sys.stdout
覆盖到控制其去向的流:
import ctypes
import sys
def MsgBox(msg):
ctypes.windll.user32.MessageBoxA(0, msg, 'MsgBox', 1)
class Printer:
def __init__(self, original, alternate, use_alternate):
self.original = original
self.alternate = alternate
self.use_alternate = use_alternate
def write(self, msg):
if self.use_alternate:
return self.alternate(msg)
return self.original(msg)
sys.stdout = printer = Printer(sys.stdout.write, MsgBox, True)
您的旗帜是printer.use_alternate
。除了更容易控制之外,这也与Python 2兼容,即使Python 2 print
是一个声明。保留print
添加的换行符确实有一点点缺点,但可以使用alternate
lambda msg: MsgBox(msg.strip())
。
醇>