Pickle.dump failed. Cannot find 'lcapy.expressionclasses.ConstantFrequencyResponseDomainImpedance'
yuxiangwei0808 opened this issue · 6 comments
I am trying to save the lcapy circuit using pickle.dump:
from lcapy import *
import pickle
circuit = Circuit('**.net')
with open('circuit.pkl', 'wb') as f:
pickle.dump(circuit, f)
But it returns: _pickle.PicklingError: Can't pickle <class 'lcapy.expressionclasses.ConstantFrequencyResponseDomainImpedance'>: attribute lookup ConstantFrequencyResponseDomainImpedance on lcapy.expressionclasses failed.
However, I cannot find ConstantFrequencyResponseDomainImpedance anywhere in the source code. How to solve this problem?
ConstantFrequencyResponseDomainImpedance
, like most of the domain classes, is dynamically created in expressionclasses.py:103
.
I have not used serialization with Lcapy so would appreciate any suggestions of how to make this work.
I tried to make use of multiprocessing allowing me to do several circuit analyses in parallel. Unfortunately there is the same issue with pickling. I have also tried using dill as pickler, but this also didn't work. Unfortunately I am a python newbie and I hardly undestand the details of that problem, but I would appreciate it a lot if this issue could be solved. Maybe this could help:
https://oegedijk.github.io/blog/pickle/dill/python/2020/11/10/serializing-dill-references.html
Ah, I think I this is because the expression classes are being lazily defined. Coincidentally, I have been working on an approach to statically define them. This should fix the problem but there are over a 100 to define.
I underestimated the number of classes that were lazily defined. There are 254! Anyway, I have created a branch called classes
that statically defines them. Can you test this please?
@mph- Thank you very much for your quick support!
I have manually installed the classes branch in my venv.
Is there any way to check if I am really using the right lcapy version?
This is my script:
from lcapy import Circuit, lcapy_version
import dill
import pickle
print(f"{lcapy_version=}")
c = Circuit("""
V 1 0;
R 1 2;
C 2 0;
""")
try:
print("\n### Save to file using pickle:")
with open('circuit1.pkl', 'wb') as fp:
pickle.dump(c, fp)
except Exception as e:
print(e)
try:
print("\n### Save to file using dill:")
with open('circuit2.pkl', 'wb') as fp:
dill.dump(c, fp)
except Exception as e:
print(e)
try:
print("\n### Save to file using dill with recurse setting:")
with open('circuit2.pkl', 'wb') as fp:
dill.settings['recurse'] = True
dill.dump(c, fp)
except Exception as e:
print(e)
And this is the output:
lcapy_version='1.15.dev0'
### Save to file using pickle:
cannot pickle 'module' object
### Save to file using dill:
cannot pickle '_global_parameters' object
### Save to file using dill with recurse setting:
maximum recursion depth exceeded while getting the repr of an object
Unfortunately there is still something missing.
I'm getting the same problems :-(
One problem is that serialization is failing for SymPy's _global_parameters
class.