python 是否以错误的顺序从 swip 中删除了实例?可以修改吗?
does python delete instances from swip in wrong order? Can it be modified?
我使用 SWIG 在 C++ 中包装了一些 classes。我的 python 脚本看起来像
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
inp = pyinput.Input("heter1d/1d1g_heter")
geo = pygeom.ProbGeom1D(inp)
state = pystate.State1D(inp, geo);
equation = pyeqfactory.EqFactory1D.New(state)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
solver.solve_eigenproblem()
print state.get_keff()
并且我从智能指针 class 中收到错误,因为一个实例在被删除时仍由其他实例拥有
--------------------------------------------------------
An error occurred in line <114> of file </home/segonpin/lib/dealii/source/base/subscriptor.cc> in function
virtual dealii::Subscriptor::~Subscriptor()
The violated condition was:
counter == 0
The name and call sequence of the exception was:
ExcInUse (counter, object_info->name(), infostring)
Additional Information:
Object of class N6dealii13TriangulationILi1ELi1EEE is still used by 1 other objects.
(Additional information: <none>)
See the entry in the Frequently Asked Questions of deal.II (linked to from http://www.dealii.org/) for a lot more information on what this error means and how to fix programs in which it happens.
Stacktrace:
-----------
#0 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Subscriptor::~Subscriptor()
#1 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Triangulation<1, 1>::~Triangulation()
#2 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so: Forest::ProbGeom<1>::~ProbGeom()
#3 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#4 python: PyObject_Call
#5 python: PyObject_CallFunctionObjArgs
#6 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#7 python: ) [0x4fd4e6]
#8 python: PyDict_SetItem
#9 python: _PyModule_Clear
#10 python: PyImport_Cleanup
#11 python: Py_Finalize
#12 python: Py_Main
#13 /lib/x86_64-linux-gnu/libc.so.6: __libc_start_main
#14 python: _start
--------------------------------------------------------
当我以正确的顺序手动删除产生问题的两个 class 时,错误消失了
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
inp = pyinput.Input("heter1d/1d1g_heter")
geo = pygeom.ProbGeom1D(inp)
state = pystate.State1D(inp, geo);
equation = pyeqfactory.EqFactory1D.New(state)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
solver.solve_eigenproblem()
print state.get_keff()
# these two lines solve the problem
del state
del geo
不应该是python按相同的顺序删除这些实例(因为geo
在state
的构造函数中使用)?谢谢!
2017 年 2 月 15 日编辑,11:19。
我可以添加一些额外的原因来说明为什么我需要按特定顺序删除。我正在使用 swig 来解析一个 c++ 库 (www.dealii.org),当我创建一个 B 的实例需要一个 A 的实例才有意义时,A 中的一个计数器会增加,表示它由 B 拥有。这用于删除对象(B 需要 A 存在,所以我们在删除 A 之前删除 B)。如果您以其他方式进行操作,则会出现错误。在这种情况下,python 实例包含其中一些依赖项,因此我必须删除特定其他对象中的对象以避免出现错误消息。
我已经向 python 析构函数添加了一些消息
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
def deltalk(self):
print type(self).__name__ ," die"
pyinput.Input.__del__ = deltalk
pygeom.ProbGeom1D.__del__ = deltalk
pystate.State1D.__del__ = deltalk
pyeqfactory.EqFactory1D.__del__ = deltalk
pyeigenprobfactory.EigenProbFactory1D.__del__ = deltalk
pyeigensolver.EigenSolver1D.__del__ = deltalk
pypostprocessing.PostProcessing1D.__del__ = deltalk
inp = pyinput.Input("heter1d/1d1g_heter")
geo = pygeom.ProbGeom1D(inp)
state = pystate.State1D(inp, geo);
equation = pyeqfactory.EqFactory1D.New(state)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
当我 运行 它时,我发现它没有以我需要的方式进行破坏(在 state
引发 C++ 错误之前破坏 geo
)
$ python test2_forest.py
EigenSolver1D die
ProbGeom1D die
--------------------------------------------------------
An error occurred in line <114> of file </home/segonpin/lib/dealii/source/base/subscriptor.cc> in function
virtual dealii::Subscriptor::~Subscriptor()
The violated condition was:
counter == 0
The name and call sequence of the exception was:
ExcInUse (counter, object_info->name(), infostring)
Additional Information:
Object of class N6dealii13TriangulationILi1ELi1EEE is still used by 1 other objects.
(Additional information: <none>)
See the entry in the Frequently Asked Questions of deal.II (linked to from http://www.dealii.org/) for a lot more information on what this error means and how to fix programs in which it happens.
Stacktrace:
-----------
#0 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Subscriptor::~Subscriptor()
#1 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Triangulation<1, 1>::~Triangulation()
#2 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so: Forest::ProbGeom<1>::~ProbGeom()
#3 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#4 python: PyObject_Call
#5 python: PyObject_CallFunctionObjArgs
#6 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#7 python: ) [0x4fd4e6]
#8 python: PyDict_SetItem
#9 python: _PyModule_Clear
#10 python: PyImport_Cleanup
#11 python: Py_Finalize
#12 python: Py_Main
#13 /lib/x86_64-linux-gnu/libc.so.6: __libc_start_main
#14 python: _start
考虑到这种依赖性,有没有通用的方法告诉 python 删除对象?或者我应该在每个 class?
的析构函数中明确说明
谢谢
以防将来有人发现同样的问题,我找到了一种方法,可以使用 atexit
按我想要的顺序调用删除。
不干净但实用的解决方案
不是很干净,但我会是这样的:
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
def goodbye() :
print "Goodbye!!\n"
import atexit
atexit.register(goodbye)
def deltalk(self):
print self.__class__.__name__ ," die"
pyinput.Input.__del__ = deltalk
pygeom.ProbGeom1D.__del__ = deltalk
pystate.State1D.__del__ = deltalk
pyeqfactory.Equation1D.__del__ = deltalk
pyeigenprobfactory.EigenProb1D.__del__ = deltalk
pyeigensolver.EigenSolver1D.__del__ = deltalk
pypostprocessing.PostProcessing1D.__del__ = deltalk
inp = pyinput.Input("heter1d/1d1g_heter")
atexit.register(inp.__del__)
geo = pygeom.ProbGeom1D(inp)
atexit.register(geo.__del__)
state = pystate.State1D(inp, geo);
atexit.register(state.__del__)
equation = pyeqfactory.EqFactory1D.New(state)
atexit.register(equation.__del__)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
atexit.register(eigenprob.__del__)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
atexit.register(solver.__del__)
当我 运行 我得到的脚本时
$ python test2_forest.py
EigenSolver1D die
EigenProb1D die
Equation1D die
State1D die
State1D die
ProbGeom1D die
Input die
Goodbye!!
Input die
EigenProb1D die
State1D die
ProbGeom1D die
EigenSolver1D die
Equation1D die
如果能直接修改构造函数就更好了
如果我可以像下面的例子那样在构造函数中添加 atexit.register
会容易得多
#!/usr/bin/python
import atexit
class Foo(object):
def __init__(self, id):
self.id = id
atexit.register(self.__del__)
def __del__(self):
print(self.id, " says bye")
a = Foo(1)
b = Foo(2)
c = Foo(3)
但是 classes 是在 c++ 中定义并使用 SWIG 解析的,所以我需要修改现有 class 定义的构造函数来这样做,所以更容易做它手动为一个短节目。
修改现有构造函数...
如果您必须对许多 classes 执行此操作,但如果您仍想避免手动注册,则这不是最佳选择。 class foo 如下
#simplefoo.py
class Foo(object):
def __init__(self, id):
self.id = id
现有class的构造函数可以修改如下
#test.py
from simplefoo import Foo
# first: I load the module atexit and register the bye function
import atexit
def bye():
print("Bye bye!")
atexit.register(bye)
# second: I add the destructor that talks loudly
def del_ini(self):
print(self.id, " says bye")
Foo.__del__ = del_ini
# third: I modify the original constructor. This is ugly
Foo.ini_old = Foo.__init__
def ini_new(self, id):
self.ini_old(id)
atexit.register(self.__del__)
Foo.__init__ = ini_new
# fourth: I create objects and finish the program them to see what happens
a = Foo(1)
b = Foo(2)
c = Foo(3)
当我们 运行 我们得到脚本时
$ python3 test.py
3 says bye
2 says bye
1 says bye
Bye bye!
3 says bye
1 says bye
2 says bye
谢谢。
我使用 SWIG 在 C++ 中包装了一些 classes。我的 python 脚本看起来像
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
inp = pyinput.Input("heter1d/1d1g_heter")
geo = pygeom.ProbGeom1D(inp)
state = pystate.State1D(inp, geo);
equation = pyeqfactory.EqFactory1D.New(state)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
solver.solve_eigenproblem()
print state.get_keff()
并且我从智能指针 class 中收到错误,因为一个实例在被删除时仍由其他实例拥有
--------------------------------------------------------
An error occurred in line <114> of file </home/segonpin/lib/dealii/source/base/subscriptor.cc> in function
virtual dealii::Subscriptor::~Subscriptor()
The violated condition was:
counter == 0
The name and call sequence of the exception was:
ExcInUse (counter, object_info->name(), infostring)
Additional Information:
Object of class N6dealii13TriangulationILi1ELi1EEE is still used by 1 other objects.
(Additional information: <none>)
See the entry in the Frequently Asked Questions of deal.II (linked to from http://www.dealii.org/) for a lot more information on what this error means and how to fix programs in which it happens.
Stacktrace:
-----------
#0 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Subscriptor::~Subscriptor()
#1 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Triangulation<1, 1>::~Triangulation()
#2 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so: Forest::ProbGeom<1>::~ProbGeom()
#3 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#4 python: PyObject_Call
#5 python: PyObject_CallFunctionObjArgs
#6 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#7 python: ) [0x4fd4e6]
#8 python: PyDict_SetItem
#9 python: _PyModule_Clear
#10 python: PyImport_Cleanup
#11 python: Py_Finalize
#12 python: Py_Main
#13 /lib/x86_64-linux-gnu/libc.so.6: __libc_start_main
#14 python: _start
--------------------------------------------------------
当我以正确的顺序手动删除产生问题的两个 class 时,错误消失了
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
inp = pyinput.Input("heter1d/1d1g_heter")
geo = pygeom.ProbGeom1D(inp)
state = pystate.State1D(inp, geo);
equation = pyeqfactory.EqFactory1D.New(state)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
solver.solve_eigenproblem()
print state.get_keff()
# these two lines solve the problem
del state
del geo
不应该是python按相同的顺序删除这些实例(因为geo
在state
的构造函数中使用)?谢谢!
2017 年 2 月 15 日编辑,11:19。
我可以添加一些额外的原因来说明为什么我需要按特定顺序删除。我正在使用 swig 来解析一个 c++ 库 (www.dealii.org),当我创建一个 B 的实例需要一个 A 的实例才有意义时,A 中的一个计数器会增加,表示它由 B 拥有。这用于删除对象(B 需要 A 存在,所以我们在删除 A 之前删除 B)。如果您以其他方式进行操作,则会出现错误。在这种情况下,python 实例包含其中一些依赖项,因此我必须删除特定其他对象中的对象以避免出现错误消息。
我已经向 python 析构函数添加了一些消息
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
def deltalk(self):
print type(self).__name__ ," die"
pyinput.Input.__del__ = deltalk
pygeom.ProbGeom1D.__del__ = deltalk
pystate.State1D.__del__ = deltalk
pyeqfactory.EqFactory1D.__del__ = deltalk
pyeigenprobfactory.EigenProbFactory1D.__del__ = deltalk
pyeigensolver.EigenSolver1D.__del__ = deltalk
pypostprocessing.PostProcessing1D.__del__ = deltalk
inp = pyinput.Input("heter1d/1d1g_heter")
geo = pygeom.ProbGeom1D(inp)
state = pystate.State1D(inp, geo);
equation = pyeqfactory.EqFactory1D.New(state)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
当我 运行 它时,我发现它没有以我需要的方式进行破坏(在 state
引发 C++ 错误之前破坏 geo
)
$ python test2_forest.py
EigenSolver1D die
ProbGeom1D die
--------------------------------------------------------
An error occurred in line <114> of file </home/segonpin/lib/dealii/source/base/subscriptor.cc> in function
virtual dealii::Subscriptor::~Subscriptor()
The violated condition was:
counter == 0
The name and call sequence of the exception was:
ExcInUse (counter, object_info->name(), infostring)
Additional Information:
Object of class N6dealii13TriangulationILi1ELi1EEE is still used by 1 other objects.
(Additional information: <none>)
See the entry in the Frequently Asked Questions of deal.II (linked to from http://www.dealii.org/) for a lot more information on what this error means and how to fix programs in which it happens.
Stacktrace:
-----------
#0 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Subscriptor::~Subscriptor()
#1 /home/segonpin/lib/dealii-8.4.bin/lib/libdeal_II.g.so.8.4.2: dealii::Triangulation<1, 1>::~Triangulation()
#2 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so: Forest::ProbGeom<1>::~ProbGeom()
#3 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#4 python: PyObject_Call
#5 python: PyObject_CallFunctionObjArgs
#6 /home/segonpin/codessebas/dealii-neutron-transport/python/_pygeom.so:
#7 python: ) [0x4fd4e6]
#8 python: PyDict_SetItem
#9 python: _PyModule_Clear
#10 python: PyImport_Cleanup
#11 python: Py_Finalize
#12 python: Py_Main
#13 /lib/x86_64-linux-gnu/libc.so.6: __libc_start_main
#14 python: _start
考虑到这种依赖性,有没有通用的方法告诉 python 删除对象?或者我应该在每个 class?
的析构函数中明确说明谢谢
以防将来有人发现同样的问题,我找到了一种方法,可以使用 atexit
按我想要的顺序调用删除。
不干净但实用的解决方案
不是很干净,但我会是这样的:
#!/usr/bin/python
import pyinput
import pygeom
import pystate
import pyeqfactory
import pyeigenprobfactory
import pyeigensolver
def goodbye() :
print "Goodbye!!\n"
import atexit
atexit.register(goodbye)
def deltalk(self):
print self.__class__.__name__ ," die"
pyinput.Input.__del__ = deltalk
pygeom.ProbGeom1D.__del__ = deltalk
pystate.State1D.__del__ = deltalk
pyeqfactory.Equation1D.__del__ = deltalk
pyeigenprobfactory.EigenProb1D.__del__ = deltalk
pyeigensolver.EigenSolver1D.__del__ = deltalk
pypostprocessing.PostProcessing1D.__del__ = deltalk
inp = pyinput.Input("heter1d/1d1g_heter")
atexit.register(inp.__del__)
geo = pygeom.ProbGeom1D(inp)
atexit.register(geo.__del__)
state = pystate.State1D(inp, geo);
atexit.register(state.__del__)
equation = pyeqfactory.EqFactory1D.New(state)
atexit.register(equation.__del__)
eigenprob = pyeigenprobfactory.EigenProbFactory1D.New(state, equation)
atexit.register(eigenprob.__del__)
solver = pyeigensolver.EigenSolver1D(state, eigenprob)
atexit.register(solver.__del__)
当我 运行 我得到的脚本时
$ python test2_forest.py
EigenSolver1D die
EigenProb1D die
Equation1D die
State1D die
State1D die
ProbGeom1D die
Input die
Goodbye!!
Input die
EigenProb1D die
State1D die
ProbGeom1D die
EigenSolver1D die
Equation1D die
如果能直接修改构造函数就更好了
如果我可以像下面的例子那样在构造函数中添加 atexit.register
会容易得多
#!/usr/bin/python
import atexit
class Foo(object):
def __init__(self, id):
self.id = id
atexit.register(self.__del__)
def __del__(self):
print(self.id, " says bye")
a = Foo(1)
b = Foo(2)
c = Foo(3)
但是 classes 是在 c++ 中定义并使用 SWIG 解析的,所以我需要修改现有 class 定义的构造函数来这样做,所以更容易做它手动为一个短节目。
修改现有构造函数...
如果您必须对许多 classes 执行此操作,但如果您仍想避免手动注册,则这不是最佳选择。 class foo 如下
#simplefoo.py
class Foo(object):
def __init__(self, id):
self.id = id
现有class的构造函数可以修改如下
#test.py
from simplefoo import Foo
# first: I load the module atexit and register the bye function
import atexit
def bye():
print("Bye bye!")
atexit.register(bye)
# second: I add the destructor that talks loudly
def del_ini(self):
print(self.id, " says bye")
Foo.__del__ = del_ini
# third: I modify the original constructor. This is ugly
Foo.ini_old = Foo.__init__
def ini_new(self, id):
self.ini_old(id)
atexit.register(self.__del__)
Foo.__init__ = ini_new
# fourth: I create objects and finish the program them to see what happens
a = Foo(1)
b = Foo(2)
c = Foo(3)
当我们 运行 我们得到脚本时
$ python3 test.py
3 says bye
2 says bye
1 says bye
Bye bye!
3 says bye
1 says bye
2 says bye
谢谢。