编辑:因为似乎没有解决方案,或者我正在做一些没人知道的非标准的东西 - 我会修改我的问题也要问:当python应用程序创建时,完成日志记录的最佳方法是什么很多系统调用?
我的应用程序有两种模式.在交互模式下,我希望所有输出都转到屏幕以及日志文件,包括来自任何系统调用的输出.在守护程序模式下,所有输出都将转到日志中.守护进程模式很好用os.dup2().我无法找到一种方法将所有输出"发送"到交互模式的日志,而无需修改每个系统调用.
换句话说,我想要命令行'tee'的功能,用于python应用程序生成的任何输出,包括系统调用输出.
澄清:
要重定向所有输出,我会做这样的事情,并且效果很好:
# open our log file
so = se = open("%s.log" % self.name, 'w', 0)
# re-open stdout without buffering
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
# redirect stdout and stderr to the log file opened above
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
Run Code Online (Sandbox Code Playgroud)
关于这一点的好处是它不需要来自其余代码的特殊打印调用.该代码还运行一些shell命令,因此不必单独处理每个输出.
简单地说,我想做同样的事情,除了重复而不是重定向.
起初以为我认为简单地扭转它们dup2应该有效.为什么不呢?这是我的测试:
import os, sys
### my broken solution:
so = se = open("a.log", 'w', 0)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
os.dup2(sys.stdout.fileno(), so.fileno())
os.dup2(sys.stderr.fileno(), se.fileno()) …Run Code Online (Sandbox Code Playgroud) 我在类的__del__函数中得到一个NameError.我不明白为什么在函数__del__中无法访问'open'.我使用的是Python 3.4.0
Python代码:
class Contoller:
...
def __del__(self):
store = {}
...
pickle.dump(store, open('data.p', 'wb'))
class MyWindow(Gtk.Window):
def __init__(self):
...
self.controller = Contoller(self)
...
self.connect("delete-event", self.quit)
...
...
def quit(self, widget, event):
del self.controller
Gtk.main_quit()
Run Code Online (Sandbox Code Playgroud)
错误信息:
Traceback (most recent call last):
File "main.py", line 69, in __del__
NameError: name 'open' is not defined
Run Code Online (Sandbox Code Playgroud) 在python 3中编写自定义__del__方法或依赖stdlib 1中的一个用例是什么?也就是说,在什么情况下它是相当安全的,并且可以做一些没有它的事情很难做到的事情?
出于很多好的理由(1 2 3 4 5 6),通常的建议是避免__del__使用上下文管理器或手动执行清理:
__del__如果对象在intrepreter出口2上处于活动状态,则不保证会被调用.gc暗示的不可预测性更不确定.__del____del__必须仔细编写:
__init__可能不存在,因为__init__可能引发了异常;stderr);更新:
PEP 442在行为上做出了重大改进__del__.虽然我的第1-4点仍然有效?
更新2:
一些顶级的python库包含__del__在后PEP 442 python(即python 3.4+)中的使用.我想我的观点3在PEP 442之后不再有效,其他点被接受为对象终结的不可避免的复杂性.
1我将问题从编写自定义__del__方法扩展到包括依赖于__del__stdlib.
2似乎__del__总是在更新版本的Cpython中调用解释器退出(有没有人有反例?).然而,对于__del__可用性的目的并不重要:文档明确地不提供对此行为的保证,因此不能依赖它(它可能在将来的版本中发生变化,在非CPython解释器中可能会有所不同) .
我有一个包含我需要的文件处理功能的类.另一个类创建了一个实例,filehandler并在不确定的时间内使用它.最终,它caller被摧毁了,它摧毁了唯一的引用filehandler.
filehandler关闭文件的最佳方法是什么?
我目前使用__del__(self)但在看到几个 不同的 问题 和文章后,我认为这被认为是一件坏事.
class fileHandler:
def __init__(self, dbf):
self.logger = logging.getLogger('fileHandler')
self.thefile = open(dbf, 'rb')
def __del__(self):
self.thefile.close()
Run Code Online (Sandbox Code Playgroud)
这是处理程序的相关部分.该类的重点是抽象出使用底层文件对象的细节,并避免不必要地将整个文件读入内存.但是,处理底层文件的一部分是在对象超出范围时关闭它.
本caller不应该知道或关心参与的细节filehandler.filehandler当它超出范围时,释放所涉及的任何必要资源是我们的工作.这是它首先被抽象的原因之一.所以,我似乎面临着将filehandler代码移动到调用对象或处理漏洞抽象的问题.
思考?
我有一个内部数据库连接的对象,它在整个生命周期中都是活动的.在程序运行结束时,必须提交和关闭连接.到目前为止,我已经使用了一个显式close方法,但这有点麻烦,特别是当调用代码中发生异常时.
我正在考虑使用这种__del__方法来关闭,但经过一些在线阅读后我有所顾虑.这是一种有效的使用模式吗?我可以确定内部资源是否可以__del__正确释放?
这次讨论提出了类似的问题但没有找到令人满意的答案 我不想有一个显式的close方法,并且使用with不是一个选项,因为我的对象不像开放式播放关闭那样简单,而是作为另一个更大的对象的成员保存,使用它在GUI中运行时.
C++有完美的工作析构函数,可以安全地释放资源,所以我认为Python也有同意的东西.由于某种原因,似乎并非如此,社区中的许多人发誓反对__del__.那么替代方案是什么?
我知道__del__Python 类的函数并没有像许多人期望的那样被处理:作为析构函数。
我还了解到,有更多“Pythonic”并且可以说是更优雅的整理方法,特别是使用with 构造。
然而,当编写可能被不太熟悉 python 方式的读者使用的代码时,当清理很重要时,是否有一种优雅的方法可以让我简单地__del__可靠地作为析构函数工作,而不干扰 python 的自然使用__del__?
作为析构函数的期望__del__似乎并非不合理,同时也很常见。所以我只是想知道是否有一种优雅的方式让它按照预期工作——忽略关于它的 Python 优点的许多争论。
首先,为长期解释道歉.
class A(object):
def __init__(self, klass):
print "A::__init__()"
self._klass = klass
def __call__(self):
print "A::__call__()"
return self._klass()
def __del__(self):
print "A::__del__()"
@A
class B(object):
def __init__(self):
print "B::__init__()"
def main():
b = B()
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
A::__init__()
A::__call__()
B::__init__()
A::__del__()
Run Code Online (Sandbox Code Playgroud)
class A(object):
def __init__(self, klass):
print "A::__init__()"
self._klass = klass
def __call__(self):
print "A::__call__()"
return self._klass()
def __del__(self):
print "A::__del__()"
class Parent1(object):
def __init__(self):
print "Parent1:: __init__()"
super(Parent1, self).__init__() …Run Code Online (Sandbox Code Playgroud) 我有类似的东西:
a = [instance1, instance2, ...]
Run Code Online (Sandbox Code Playgroud)
如果我做了
del a[1]
Run Code Online (Sandbox Code Playgroud)
instance2从列表中删除,但是实例2的析构函数方法是否被调用?
我对此感兴趣,因为我的代码使用了大量内存,我需要释放内存从列表中删除实例.
经过多次检查后,我确实发现了有关该主题的不一致信息.
在某些情况下,我确实发现__init__ and __del__python等同于构造函数和析构函数.这似乎是真的__init__,因为我看到它在创建类时被调用; 但__del__永远不会被调用,当程序结束.
在其他情况下,我确实发现这__del__很糟糕,你必须手动解除分配所有内容.
现在,问题是:哪个是哪个?因为使用unittest.TestCase类,当我调用__del__它时永远不会被调用.可悲的是我无法使用拆卸,因为我需要在测试运行之前启动一个进程,并在完成测试后结束它
在我的Python程序中,我创建了一个自定义对象。通过接收 CTRL-C 信号退出该程序。但是,__del__程序退出时不会调用该函数。当程序退出时,该程序创建的所有对象都应该被删除,但是为什么该__del__函数没有被调用呢?现在,为了进行一些清理,我决定进行atexit模块。还有更优雅的方法吗?实际上,我想用它RAII in C++来管理我的 python 对象,我可以这样做吗?