pickling class method

前端 未结 2 1166
广开言路
广开言路 2020-12-07 02:45

I have a class whose instances need to format output as instructed by the user. There\'s a default format, which can be overridden. I implemented it like this:



        
相关标签:
2条回答
  • 2020-12-07 03:17

    For pickling of class instances or functions (and therefore methods), Python's pickle depend that their name is available as global variables - the reference to the method in the dictionary points to a name that is not available in the global name space - which iis better said "module namespace" -

    You could circunvent that by customizing the pickling of your class, by creating teh "__setstate__" and "__getstate__" methods - but I think you be better, since the formatting function does not depend on any information of the object or of the class itself (and even if some formatting function does, you could pass that as parameters), and define a function outside of the class scope.

    This does work (Python 3.2):

    def default_float_format( x):
        return '{:.2%}'.format(x)
    
    class A:
    
      def __init__(self, params):
        # ...
        # by default printing all float values as percentages with 2 decimals
        self.format_functions = {float: default_float_format}
      def __str__(self):
        # uses self.format_functions to format output
        pass
    
    a = A(1)
    pickle.dumps(a)
    
    0 讨论(0)
  • 2020-12-07 03:19

    If you use the dill module, either of your two approaches will just "work" as is. dill can pickle lambda as well as instances of classes and also class methods.

    No need to pollute the namespace and break encapsulation, as you said you didn't want to do… but the other answer does.

    dill is basically ten years or so worth of finding the right copy_reg function that registers how to serialize the majority of objects in standard python. Nothing special or tricky, it just takes time. So why doesn't pickle do this for us? Why does pickle have this restriction?

    Well, if you look at the pickle docs, the answer is there: https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled

    Basically: Functions and classes are pickled by reference.

    This means pickle does not work on objects defined in __main__, and it also doesn't work on many dynamically modified objects. dill registers __main__ as a module, so it has a valid namespace. dill also given you the option to not pickle by reference, so you can serialize dynamically modified objects… and class instances, class methods (bound and unbound), and so on.

    0 讨论(0)
提交回复
热议问题