我使用的Python 2.6.6,我需要重载默认的蟒纹功能。 我需要做的,因为此代码的系统,其中内置的功能已被用来生成输出上使用,否则没有任何输出。
所以,仅仅举例来说,如果你有一个python脚本是这样的:
from __future__ import print_function
def NewPrint(Str):
with open("somefile.txt","a") as AFile:
AFile.write(Str)
def OverloadPrint():
global print
print = NewPrint
OverloadPrint()
print("ha")
它工作正常。 输入到“超载”打印是NewPrint指定的文件中。
现在,考虑到这一点,我想能够运行的几行以上,并具有打印做脚本的整个执行过程中NewPrint做什么。 现在,如果我从另一个调用模块使用打印功能,将使用内置的打印,而不是一个我刚刚改写。 我想这已经是与命名空间和内置插件,但我的蟒蛇是不够好。
编辑:
我试图保持简单,但看起来像这样造成更多的混乱......
- 该重载打印将打印到一个GUI的功能,所以无需关心重定向如果函数过载。
我知道我的例子并没有做什么的打印功能实际执行。 的,我怎么想的编码它是一个更好的例子(仍然不是很大,我知道):
def hli_print(*args, **kw): """ print([object, ...], sep=' ', end='\n', file=sys.stdout) """ sep = kw.get('sep', ' ') end = kw.get('end', '\n') File = kw.get('file', sys.stdout) args = [str(arg) for arg in args] string = sep.join(args) + end File.write(string) hli_Print(string)
从2上面可以看到我不得不使用打印到GUI“hli_Print”的功能,它是一个C ++函数通过了一大口包装暴露。
- 我们只使用标准库和我们自己痛饮的包装,也是我们的开发人员使用打印的功能(习惯3.X)。 所以,我真的不担心很多关于其他模块调用打印,并具有别的东西来代替。
从所有的意见,我想这只是使用一些print_()函数,而不是打印()(这是我们目前正在做的)可能是最好的,但我真的很好奇,看看是否在蟒蛇有可能做什么我描述。
我不认为你的问题使任何意义。
首先,如果你正在运行的Python 2.6,一切导入等,将使用print
语句,即使你自己的模块使用print
功能。 因此,重载函数不会影响任何东西。
其次,你说“我需要做的,因为此代码的系统,其中内置的功能已被用来生成输出上使用,否则没有任何输出。” 那么,你的NewPrint
不是一个内置的功能,所以这无论如何也不会帮助。
另外值得一提的是,你的NewPrint
没有实现大部分的功能print
功能,甚至认为它确实实现了位,但它确实错( print(s)
将打印s
跟着一个换行符 )。 所以,如果你没有更换内置print
与你的功能,你只是最终破坏最自己的代码和任何你依赖STDLIB /第三方代码。
这可能是你可以完成你通过创建一个类文件对象,取代想要什么sys.stdout
。 否则,我看不出任何东西可以工作。 例如:
class FakeStdOut(object):
# … lots of other stuff to implement or inherit
def write(s):
with open("somefile.txt", "a") as f:
f.write(s)
def OverloadPrint():
sys.stdout = FakeStdOut()
但即使这样的作品,它可能不是你真正想要的。 对于一个快速和肮脏的脚本,有缺陷的外壳在一个平台上,这有时是一个方便的想法。 但除此之外,它可能会导致你从长远来看,更多的麻烦比想出一个更好的解决方案。 这里只是几件事情,可以去错了(只是作为例子,而不是一个详尽的列表)
- 如果你想改变输出去的文件,你必须修改剧本。 如果用来代替
>>
在外壳,你可以只调用脚本不同。 - 有人阅读或调试代码(如,说,你,你忘了三个月后它是如何工作)会发生的事情感到惊讶。
- 有些STDLIB /第三方/同事/等。 代码调用将检查
stdout
是一个tty你做出改变之前,对自己进行配置的交互输出。 - 一些代码将打印你有机会重新定向之前,你会花几个小时试图找出如何重新安排事情解决该问题。
- 你必须知道如何实现“类文件对象”完全和这一概念没有完全定义2.6或者它将与一些代码打破。
- 冥冥之中,有你以为是一些代码
print
ING,但它实际上是,比如说, log
更改或写入sys.stderr
或做别的东西,所以你给自己的安全,你现在登录的一切虚假的安全感在somefile.txt
,否则不会发现直到第6个月后,当你迫切需要失踪信息,在客户现场调试问题。
既然你编辑的问题,这里的一些进一步的反应:
从所有的评论我想这只是使用一些print_()函数,而不是打印的()
是的,这是一个更合理的选择。 但我可能不会把它print_
。 而且它更简单把“做或不做”逻辑里面的功能,而不是进出全局名称(特别是因为你要拧,最多在某个时刻的交换实现,如果你的代码是不是都在一个大模块)。
我曾在一个类似用途的情况下,一个项目:我们有我们想去的系统日志,也去GUI“登录窗口”,如果它是打开的邮件。 因此,我们写了一个glog
功能包,最多,没有人抱怨说,他们想写print
代替。 (事实上,在球队至少一个家伙很是高兴,他可以使用print
快速和肮脏的打印输出在调试时不影响实际产出,尤其是当他不得不调试GUI日志代码。)
但是,这只是因为我们没有与新的(当时)的经验logging
组件。 现在,我想我会创建一个logging
Handler
实现,写入GUI窗口,只需添加该处理程序,并使用标准的logging
比比皆是方法。 这听起来像这可能是你最好的选择。
此外,最后一个可能是无关的枝节问题:
我们只使用标准库和我们自己痛饮的包装,也是我们的开发人员使用打印的功能(习惯3.X)。
那么,为什么不首先使用3.x的? 显然3.X有实际3.x的标准库,而不是什么样的接近3.x的标准库,如果你做一些__future__
语句,SWIG可与3.X ...
作为@ abarnert的答案和一些评论人士指出,更换print
可能不是一个好主意。 但只是为了完整起见,这里就是为什么你的代码没有成功覆盖它的其他模块。
的print
功能在模块定义__builtin__
(其被重命名为builtins
在Python 3)。 Python解释器,使一切都在__builtin__
模块的名称空间提供给它运行的所有其他代码,而无需将它导入到你的模块的自己的命名空间。 它的神奇!
然而,当你创建自己的函数命名print
(使用print = NewPrint
)它不会覆盖在原来的版本__builtin__
。 你只是建立在你的模块命名空间的影子旧的一个新的变量__builtin__
。 在global
语句不帮助,因为它只是让你告诉Python要写入你的模块的全局命名空间,而不是一个函数内的一些内部命名空间。
要替换默认的print
功能,您将需要明确取代它在__builtin__
模块。 下面是确实是一些示例代码:
from __future__ import print_function
try:
import __builtin__ as builtins # Python 2
except ImportError:
import builtins # Python 3
_print = print # keep a local copy of the original print
builtins.print = lambda *args, **kwargs: _print("foo:", *args, **kwargs)
要重复,这实在不是一个好主意。 同时确保我明白我在这个答案在谈论,我设法通过更换崩溃我的Python会议的一个print
与没有接受lambda函数file
是Python使用打印到标准错误参数。 几行后,异常处理程序并不高兴,当它得到了第二个例外,同时尝试打印另一个异常的回溯。
几乎可以肯定有更好的方式得到你想要的结果。