克服Python实例方法的限制
看起来Python在实例方法方面有一些限制。
- 实例方法不能被复制。
- 实例方法不能被序列化。
这对我来说有点麻烦,因为我在一个非常面向对象的项目中工作,在这个项目里我需要引用实例方法,而且还用到了深拷贝和序列化。序列化主要是通过多进程机制来实现的。
那么,有什么好的解决办法吗?我对复制的问题做了一些不太优雅的变通,但我希望能找到一个更好的解决方案来解决这两个问题。
有没有人有好的建议呢?
更新:
我的使用场景是:我有一个小型的事件系统。每个事件都有一个.action
属性,指向它应该触发的函数,有时候这个函数是某个对象的实例方法。
3 个回答
-3
把这个实例进行“序列化”(也就是把它变成可以保存的格式),然后在反序列化后再访问它的方法。把实例的方法进行序列化是没有意义的,因为这个方法是依赖于这个实例的。如果这个方法不依赖于实例,那就把它写成一个独立的函数。
import pickle
class A:
def f(self):
print 'hi'
x = A()
f = open('tmp', 'w')
r = pickle.dump(x, f)
f.close()
f = open('tmp', 'r')
pickled_x = pickle.load(f)
pickled_x.f()
3
REST - 表现状态转移。就是只传递状态,不传递方法。
要把一个对象X从A传到B,我们可以这样做:
A把X的状态用一种方便、容易解析的格式编码。JSON就是一种很流行的格式。
A把这个JSON文本发送给B。
B把JSON格式的X的状态解码,重新构建出X。
B必须有X的类定义,这样才能正常工作。B还需要有X的类所依赖的所有函数和其他类的定义。简单来说,A和B都需要有所有的定义。只有对象的状态表示被传来传去。
想了解更多,可以看看关于REST的文章。
http://en.wikipedia.org/wiki/Representational_State_Transfer
15
你可以尝试使用 copy_reg.pickle
来实现这个功能。在 Python 2.6 中:
import copy_reg
import types
def reduce_method(m):
return (getattr, (m.__self__, m.__func__.__name__))
copy_reg.pickle(types.MethodType, reduce_method)
这个方法并不会保存方法的 代码,只保存了它的名字;但在大多数情况下,这样做是没问题的。
这样就可以让序列化和复制都正常工作了!