我最近尝试过reload()。让我们考虑以下简单模块mother_and_child_in_same_file.py
:
class mother( object ):
def foobar( self ):
print "foobar mother"
class child( mother ):
def foobar( self ):
self.__class__ = child
# None of the two following methods is correctly working after a reload,
# except if we
# add the previous line concerning __class__; then both methods work
# correctly.
mother.foobar( self )
#super( child, self ).foobar()
print "foobar child"
在剧本中使用:
import mother_and_child_in_same_file
a = mother_and_child_in_same_file.child()
a.foobar()
print "============ RELOAD"
reload( mother_and_child_in_same_file )
a.foobar()
导致预期输出
$ python mother_and_child_in_same_file_TEST.py
foobar mother
foobar child
============ RELOAD
foobar mother
foobar child
但是只有在代码中解释的self.__class__
被强制的情况下才会强制执行。
因此问题在于,现有物体可能会松散"使用reload()时他们的类,使得必须在这些对象的每个方法的开头重新分配self.__class__
,这样在调用母亲时没有获得错误(如果我理解正确)。
这是相当沉重的,我试图使用类装饰器自动执行此操作。这是mother_and_child_in_same_file_decorator.py
模块:
def my_decorator( cls ):
def prepend_cls_instance_method_with_class_update( m ):
def prepended_method( self, *args ):
self.__class__ = cls
print "After: self.__class__ = %s" % self.__class__
m( self, *args )
return prepended_method
for method_name in dir( cls ):
if method_name[:2] == "__":
continue
method = getattr( cls, method_name )
if hasattr( method, '__call__' ):
prepended_method = prepend_cls_instance_method_with_class_update( method )
print "setattr( %s, '%s', %s )" % ( cls, method_name, prepended_method )
setattr( cls
, method_name
, prepended_method )
return cls
class mother( object ):
def foobar( self ):
print "foobar mother"
@my_decorator
class child( mother ):
def foobar( self ):
# None of the two following methods is correctly working.
#super( child, self ).foobar()
mother.foobar( self )
print "foobar child"
使用它的脚本:
import mother_and_child_in_same_file_decorator as mother_and_child_in_same_file
a = mother_and_child_in_same_file.child()
a.foobar()
print "============ RELOAD"
reload( mother_and_child_in_same_file )
a.foobar()
这导致:
$ python mother_and_child_in_same_file_decorator_TEST.py
setattr( <class 'mother_and_child_in_same_file_decorator.child'>, 'foobar', <function prepended_method at 0x7fd467568b18> )
Before: self.__class__ = <class 'mother_and_child_in_same_file_decorator.child'>
foobar mother
foobar child
============ RELOAD
setattr( <class 'mother_and_child_in_same_file_decorator.child'>, 'foobar', <function prepended_method at 0x7fd467568c80> )
Before: self.__class__ = <class 'mother_and_child_in_same_file_decorator.child'>
Traceback (most recent call last):
File "mother_and_child_in_same_file_decorator_TEST.py", line 10, in <module>
a.foobar()
File "/home/local/mse6s3/src/python/test/reload_and_super/mother_and_child_in_same_file/mother_and_child_in_same_file_decorator.py", line 9, in prepended_method
m( self, *args )
File "/home/local/mse6s3/src/python/test/reload_and_super/mother_and_child_in_same_file/mother_and_child_in_same_file_decorator.py", line 43, in foobar
mother.foobar( self )
TypeError: unbound method foobar() must be called with mother instance as first argument (got child instance instead)
我尝试过此代码的不同变体,但没有成功。我的代码出了什么问题?提前谢谢。
答案 0 :(得分:0)
重新加载后重新创建对象。它对我来说看起来更简单,它会起作用:
import mother_child
a = mother_child.child()
a.foobar()
print "============ RELOAD"
reload(mother_child)
a = mother_child.child()
a.foobar()
答案 1 :(得分:0)
@ShadowRanger(我忘了谢谢你的回答)。实际上在我的情况下,由于以下原因,在开发期间需要reloads()。 Python解释器嵌入在用C ++编写的软件中。 &#34;嵌入式翻译&#34;允许访问一些C ++数据;除此之外,它允许运行一些Python&#34; apps&#34; (在带有GUI的小型应用程序中)在C ++软件的上下文中(即能够访问和修改某些C ++数据)。
在开发这样的应用程序时,当然需要在每次修改后一次又一次地运行它。这使得reloads()成为必需,因为嵌入式解释器在每次运行之间保持活动状态。另一种可能性是在重新启动App之前重新启动嵌入式Python解释器,但目前这是不可能的。
reloads()会出现问题,因为可以执行两个或多个相同的&#34; apps&#34;上面提到的嵌入式解释器。如果导入的模块中存在重新加载,则在第一个创建的对象中启动&#34; apps&#34;不承认他们的母亲/孩子(错误类似于我原来的帖子出现)。这就是为什么在这个框架中现在很明显我应该(i)仅在开发期间使用reload()(调试标志),(ii)只运行一个&#34; app&#34;在开发期间 - 多个应用程序&#34;同时运行应该只在发布代码中测试(没有调试标志---所以没有reload())。