简体   繁体   English

重装模块后,Python中的对象类型转换? [用于即时代码更改]

[英]object type casting in Python after reloading a module? [for on-the-fly code changes]

I am running an interactive python session which builds big python data-structures (5+ GB) which take a long time to load, and so I want to exploit Python on-the-fly code change abilities at its maximum (though sometimes, without having to plan too much for that ). 我正在运行一个交互式python会话,它构建了大量的 python数据结构(5+ GB),这需要花费很长时间才能加载,因此我希望最大限度地利用Python的动态代码更改能力(尽管有时候, 没有不得不为此计划太多 )。

My current problem is the following: I have an old instance of a class that I have later modified the code and reloaded the module -- I would like the old instance to be able to use the new function definitions. 我目前的问题如下:我有一个类的旧实例,我后来修改了代码并重新加载了模块 - 我希望旧实例能够使用新的函数定义。 How do I do that without just manually copying all the information from the old instance to a new fresh instance? 如果不手动将旧实例中的所有信息复制到新的实例,我该怎么做?

Here is what I have tried. 这是我尝试过的。 Suppose I have the module M.py : 假设我有模块M.py

class A():
    def f(self):
        print "old class"

Here is an interactive session: 这是一个互动环节:

import M
old_a = M.a()

# [suppose now I change the definition of M.A.f in the source file]

reload(M)
# I attempt to use the new class definition with the old instance:
M.A.f(old_a)

at which point I get the following type error from Python: 此时我从Python得到以下类型错误:

TypeError: unbound method f() must be called with A instance as first argument (got A instance instead)

Python is obviously not happy to receive an old instance of A even though they are basically functionally equivalent types (in my code) -- is there any way I could 'type cast' it to the new instance type so that Python wouldn't complain? Python显然不高兴收到A的旧实例,即使它们基本上是功能相同的类型(在我的代码中) - 有没有什么方法可以“输入”它到新的实例类型,以便Python不会抱怨? Something morally like: MAf( (MA) old_a ) ? 道德上的东西: MAf( (MA) old_a )

There is no casting in Python but you can change the class of an existing object: It is perfectly legal and does the job: Python中没有强制转换,但您可以更改现有对象的类:它完全合法并完成工作:

old_a.__class__=M.A
old_a.f()

As long as you haven't changed the relation between class methods and instance variables, changed what __init__ does or something like that this is perfectly fine. 只要你没有改变类方法和实例变量之间的关系,就改变了__init__所做的事情或类似的东西,这是完全没问题的。

EDIT: As jsbueno points out: The __init__ or __new__ methods are not called at the point of changing __class__ . 编辑:正如jsbueno指出: __init____new__方法在更改__class__ 不会被调用。 Further, the new __del__ will be called at destruction. 此外,新的__del__ 在销毁被调用。

Since you cannot cast, you need to revise your code so that these mysterious "on-the-fly code changes" can work. 由于您无法强制转换,因此您需要修改代码,以便这些神秘的“即时代码更改”可以正常工作。

Step 1. Separate Algorithm from Data. 步骤1.将算法与数据分开。 Write a very simple (and very unlikely to change) class for the raw Data. 为原始数据写一个非常简单(并且不太可能改变)的类。 Often a list of named tuples is all you'll ever need for this. 通常,您可能需要一个名为元组的列表。

Step 2. Create algorithms which work on the data objects by "wrapping" them instead of "updating" them. 步骤2.通过“包装”它们而不是“更新”它们来创建处理数据对象的算法。

Like this. 像这样。

def some_complex_algo( list_of_named_tuples ):
    for item in list_of_named_tuples:
        # some calculation
        yield NewTuple( result1, result2, ..., item )

Now you can attempt your processing: 现在您可以尝试处理:

result = list( some_complex_algo( source_data ) )

If you don't like the result, you only need to redefine your some_complex_algo and rerun it. 如果您不喜欢结果,则只需重新定义some_complex_algo并重新运行即可。 The source_data is untouched. source_data未受影响。 Indeed, it can be immutable. 实际上,它可以是不可改变的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM