0

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?

1
  • Hmm, good luck with that. I believe you have zero chance of success. Once Python is in your process, in my experience, it's there for good. Commented Jan 30, 2014 at 18:02

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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.

8 Comments

In my experience this will not yield good results. Have you experienced success in booting Python out like that?
@david inability to load new python instances
@Rob Did you test it with TPythonModule, TPythonGuiInputOutput, are they reinited ok? I test myself later.
Haven't tested anything, @Alextp. I don't have Delphi. I only read the documentation and looked at the source code.
@alextp My Python embedding experience is with the raw C API and not this Delphi wrapper. I have tried very hard to remove the Python engine from the process, and then bring it back. I failed. This is not to say that I am sure it cannot be done, just that I think you should be prepared for failure. The docs suggest that this should be possible, with some caveats: docs.python.org/2/c-api/init.html
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.