Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.177 Beiträge
 
Delphi 12 Athens
 
#5

AW: Python im Delphi ausführen (geht nicht)

  Alt 21. Jan 2021, 18:34
Jupp, so ähnlich hab ich das inzwischen auch zum Laufen bekommen.
* python-3.9.1-embed-win32.zip
* nichts konfiguriert
* und im Delphi wie bei dir, aber zusätzlich die mistigen Fatal*** auch auf False

Allerdings lässt sich der Pfad nicht dynamisch ändern. (OnBeforeLoad ist einen Hauch zu spät ... könnte maximal noch .Loaded überschreiben)
* drum, hab ich nun das Auto**** deaktiviert und versuche manuell zu laden
* war grade dabei meine zwei Demo-EXEn auszumisten und dann hochzuladen

* mit hartcodiertem Pfad geht es nun
* aber da das Programm selten im selben Pfad liegt .......


Mit AutoLoad hab ich auch noch das Problem, dass ich Variablen erst manuell löschen muß, da sie nach dem Execute erhalten bleiben, in den nächsten Aufrufen.
* grundsätzlich erstmal gut, da wir unser InitScript einzeln ausführen können und es nicht ins ArbeitsScript einfügen müssen. (bei einem Fehler würden dann nun endlich mal die Zeilennummern stimmen)
* aber zwischen der Ausführung von zwei Aufgaben sollten die Variablen nicht erhalten bleiben (früher einfach, da die Python.exe sich am Schulß eh immer beendete)
* auf die Schnelle aber nur ein Python-Script zum Löschen gefunden (im Delphi den Zugriff auf die Variablen noch nicht rausgefunden/verstanden ... egal, geht erstmal)


Also erstmal was halbwegs Nutzbbares hinbekommen,
aber nun noch versuchen das AutoLoad durch was Manuelles zu ersetzen

mit AutoLoad
Delphi-Quellcode:
procedure TForm9.PythonEngine1BeforeLoad(Sender: TObject);
begin
  { zu spät ... muß schon vor/in .Loaded erledigt worden sein, drum stehts erstmal wieder in der DFM }
  //PythonEngine1.DllPath := EdDllPath.Text;
  //PythonEngine1.DllName := EdDllName.Text;
  //PythonEngine1.RegVersion := '';
  //PythonEngine1.UseLastKnownVersion := False;

  // muß vor PythonEngine1.Initialize aufgerufen werden.
  // und da PythonEngine1.AutoLoad=True .....
  PythonEngine1.InitScript.Text := EdGlobalScript.Text;
end;

procedure TForm9.BtExecCheckClick(Sender: TObject);
begin
  EdOutput.Clear;

  //PythonEngine1.ExecString(EdInitScript.Text);
  EdResult.Text := BoolToStr(PythonEngine1.CheckExecSyntax(EdExecScript.Text), True);
end;

procedure TForm9.BtExecClick(Sender: TObject);
begin
  //PythonEngine1.InitScript.Text := EdGlobalScript.Text;
  try
    EdResult.Clear;
    EdOutput.Clear;

    // Variablen der letzten Ausführungen löschen
    { bissl was versucht, aber nichts half
    PythonEngine1.GlobalVars := nil;
    PythonEngine1.LocalVars := nil;
    PythonModule1.ClearVars;
    }

    PythonEngine1.ExecString(
        'for name in dir(): '#10
      + ' if not name.startswith("__"): '#10
      + ' del globals()[name] '#10
      + 'for name in dir(): '#10
      + ' if not name.startswith("__"): '#10
      + ' del locals()[name] '#10
      + 'del name');

    if Trim(EdInitScript.Text) <> 'then
      PythonEngine1.ExecString(EdInitScript.Text);
    PythonEngine1.ExecString(EdExecScript.Text);
  except
    on E: Exception do
      EdResult.Text := E.Message;
  end;
end;
ohne AutoLoad (aber im Initialize knallt eine Zugriffsverletzung bei Addr 0000)
Delphi-Quellcode:
procedure TForm9.BtExecClick(Sender: TObject);
begin
  if not PythonEngine1.IsHandleValid then begin
    PythonEngine1.DllPath := EdDllPath.Text;
    PythonEngine1.DllName := EdDllName.Text;
    PythonEngine1.RegVersion := '';
    PythonEngine1.UseLastKnownVersion := False;
    PythonEngine1.LoadDll;
  end;

  if not PythonEngine1.Initialized then begin
    PythonEngine1.InitScript.Text := EdGlobalScript.Text;
    PythonEngine1.Initialize;
  end;
  try

    try
      EdResult.Clear;
      EdOutput.Clear;

// // Variablen der letzten Ausführungen löschen
// { bissl was versucht, aber nichts half
// PythonEngine1.GlobalVars := nil;
// PythonEngine1.LocalVars := nil;
// PythonModule1.ClearVars;
// }
// PythonEngine1.ExecString(
// 'for name in dir(): '#10
// + ' if not name.startswith("__"): '#10
// + ' del globals()[name] '#10
// + 'for name in dir(): '#10
// + ' if not name.startswith("__"): '#10
// + ' del locals()[name] '#10
// + 'del name');

      if Trim(EdInitScript.Text) <> 'then
        PythonEngine1.ExecString(EdInitScript.Text);
      PythonEngine1.ExecString(EdExecScript.Text);
    except
      on E: Exception do
        EdResult.Text := E.Message;
    end;

  finally
    PythonEngine1.Finalize;
  end;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (21. Jan 2021 um 18:44 Uhr)
  Mit Zitat antworten Zitat