Reputation: 4781
I use D7 with Python4Delphi. After users have imported much of py-files, Python have all these modules cached. I need a way to reset Py engine. So that Py "forgets" all user-imported modules, and I have "clean" Python, w/out restarting the app. How to do it?
Upvotes: 0
Views: 1284
Reputation: 614
There is a demo showing you how to unload/reload python using P4D at https://github.com/pyscripter/python4delphi/tree/master/PythonForDelphi/Demos/Demo34. The key method that (re)creates the python components and (re)loads different versions of python is shown below:
procedure TForm1.CreatePythonComponents;
begin
if cbPyVersions.ItemIndex <0 then begin
ShowMessage('No Python version is selected');
Exit;
end;
// Destroy P4D components
FreeAndNil(PythonEngine1);
FreeAndNil(PythonType1);
FreeAndNil(PythonModule1);
{ TPythonEngine }
PythonEngine1 := TPythonEngine.Create(Self);
PyVersions[cbPyVersions.ItemIndex].AssignTo(PythonEngine1);
PythonEngine1.IO := PythonGUIInputOutput1;
{ TPythonModule }
PythonModule1 := TPythonModule.Create(Self);
PythonModule1.Name := 'PythonModule1';
PythonModule1.Engine := PythonEngine1;
PythonModule1.ModuleName := 'spam';
with PythonModule1.Errors.Add do begin
Name := 'PointError';
ErrorType := etClass;
end;
with PythonModule1.Errors.Add do begin
Name := 'EBadPoint';
ErrorType := etClass;
ParentClass.Name := 'PointError';
end;
{ TPythonType }
PythonType1 := TPythonType.Create(Self);
PythonType1.Name := 'PythonType1';
PythonType1.Engine := PythonEngine1;
PythonType1.OnInitialization := PythonType1Initialization;
PythonType1.TypeName := 'Point';
PythonType1.Prefix := 'Create';
PythonType1.Services.Basic := [bsRepr,bsStr,bsGetAttrO,bsSetAttrO];
PythonType1.TypeFlags :=
[tpfHaveGetCharBuffer,tpfHaveSequenceIn,tpfHaveInplaceOps,
tpfHaveRichCompare,tpfHaveWeakRefs,tpfHaveIter,tpfHaveClass,tpfBaseType];
PythonType1.Module := PythonModule1;
PythonEngine1.LoadDll;
end;
The demo uses the unit PythonVersions to discover installed python versions.
Upvotes: 2
Reputation: 163347
It should be sufficient to destroy and re-create the TPythonEngine
object:
OriginalOwner := GetPythonEngine.Owner;
GetPythonEngine.Free;
TPythonEngine.Create(OriginalOwner);
Destroying it calls Py_Finalize
, which frees all memory allocated by the Python DLL.
Or, if you're just using the Python API without the VCL wrappers, you can probably just call Py_NewInterpreter
on your TPythonInterface
object to get a fresh execution environment without necessarily discarding everything done before.
Upvotes: 2