Jump to content
uefi

I get value=none

Recommended Posts

Hello, I can not get the result of the script execution instead of the result I get: 

value=none 

 

uses
...PythonEngine, Vcl.PythonGUIInputOutput;
function pyscript:string;
var
 PythonEngine1:TPythonEngine;
 PythonDelphiVar1:TPythonDelphiVar;
begin
  PythonEngine1:=TPythonEngine.Create(nil);
  PythonDelphiVar1:=TPythonDelphiVar.Create(nil);
  PythonDelphiVar1.Engine:=PythonEngine1;
  //PythonEngine1.DLLName := 'python310.dll';
  PythonEngine1.LoadDll;
  PythonEngine1.ExecString('print("Hello World")');
  Result:=( 'Value = ' + PythonDelphiVar1.ValueAsString );
  FreeAndNil(PythonEngine1);
  FreeAndNil(PythonDelphiVar1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
memo2.Lines.Add(pyscript);
end;

 

image.png

image.png

Share this post


Link to post

Try this method. 

 

I've tried to document it over the code. 

 

I do not use TPythonDelphiVar because have some connotations of visual components that we don't need. 

 

This example assumes you know the type of the variable whose value you want to recover.

 

procedure TForm1.Button1Click(Sender: TObject);
var PythonEngine :TPythonEngine;
    PythonModule :TPythonModule;
    Pointer      :PPyObject;     //Pointer to create a value inside the Engine.
    VarColor     :Variant;       //Variant to recover the Color from the Engine
    PasColor     :string;        //The color in Pascal.
begin
   PythonEngine := TPythonEngine.Create(nil);
   {Documentation explains that these properties are for Embedded (not registered)
    installations of Python }
   PythonEngine.AutoLoad            := False;
   PythonEngine.DllName             := 'python311.dll';
   PythonEngine.DllPath             := 'C:\Views\senCille\bin\Win64\Python';
   PythonEngine.APIVersion          := 1013;
   PythonEngine.RegVersion          := '3.11';
   PythonEngine.UseLastKnownVersion := False;
   PythonEngine.SetPythonHome('C:\Views\senCille\bin\Win64\Python');

 

   {We create a Module that points to a special one inside PythonEngine}
   PythonModule := TPythonModule.Create(nil);
   PythonModule.Engine                := PythonEngine;
   PythonModule.ModuleName            := '__main__';

 

  try
     PythonEngine.LoadDll;

 

     {Now we are going to create a Variable inside PythonEngine}

     {p point to and Unicode string created inside the PyEngine}
     Pointer := PythonEngine.PyUnicode_FromString('Dark Blue');
     {Create the Variable Color inside PythonEngine and assigns p as his value}
     PythonModule.SetVar('Color', Pointer);


     {At this moment, the value pointed by p has two references:
      Pointer  : a pointer inside the Delphi source and
      Color : The variable inside PythonEngine.
      We call Py_DecRef to decrement this counter and allow PythonEngine to
      free this variable when not more need it}
     PythonEngine.Py_DecRef(Pointer);

 

     {We use a python script to assign a value to Color instance inside PythonEngine}

     PythonEngine.ExecString('Color = "Dark Blu"');

 

 

     {Now we retrieve a PythonEngine value contained in Color variable}
     VarColor := PythonModule.GetVarAsVariant('Color');

     {if the local variant don't have a value, we assign on by default}
     if not (VarColor = unassigned) then begin
        {We can use the Variant in our program, but we prefer a string type}
        PasColor := VarColor;
     end
     else PasColor := 'No color Assigned';

 

     ShowMessage('Value = ' + PasColor);
  finally
     PythonModule.Free;
     PythonEngine.Free;
  end;
end;

DemoVar.zip

Share this post


Link to post
2 hours ago, uefi said:

The code is too intricately written and this is not exactly what I want, I just need to get the result of the script execution into a variable after PythonEngine1.ExecString

 

You probably need a Math Parser component. The goal of a scripting language is not this. 
I think that Python doesn't have this concept of "result." 

If anyone can confirm or deny this affirmation, please do. 

 

With a Scripting language you need to assign your result to a variable and after take the value of this variable from Delphi. 

Edited by Juan C.Cilleruelo

Share this post


Link to post
19 minutes ago, uefi said:

Dude, all I needed was in the code below, why are you bringing me some kind of utter nonsense? And you offer me some shitty codes ?

Please, be civil.

Share this post


Link to post
3 hours ago, uefi said:

Dude, all I needed was in the code below. Why are you bringing me some utter nonsense? And you offer me some shitty code?

Welcome to the unique forum in the world, whose members will try to understand you, with the goal of helping you to solve some of your problems!

Good luck with your search for help! 

 

(sincerely)

Share this post


Link to post
On 1/14/2023 at 8:12 PM, uefi said:

Hello, I can not get the result of the script execution instead of the result I get: 

value=none

What did you expect to get?

Demo03 shows you how to use TPythonDelphiVar.

Edited by pyscripter

Share this post


Link to post
On 1/16/2023 at 4:14 AM, pyscripter said:

 

Demo03 shows you how to use TPythonDelphiVar.

 

On 1/15/2023 at 4:31 PM, uefi said:

PythonEngine1.ExecString('fun=("Hello World")'); Result:=( 'Value = ' + PythonEngine1.EvalStringAsStr('fun') );

Seems, you get 'none' because your 'fun' variable definition is out of scope. 

 

You try to call 'Py_RunString' under the hood

https://github.com/tangentstorm/py4d/blob/master/PythonForDelphi/Components/Sources/Core/PythonEngine.pas#L5204

https://github.com/tangentstorm/py4d/blob/master/PythonForDelphi/Components/Sources/Core/PythonEngine.pas#L3766

 

You could get more information from here: https://docs.python.org/3/c-api/veryhigh.html

Quote
PyObject *PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags)
Return value: New reference.

Execute Python source code from str in the context specified by the objects globals and locals with the compiler flags specified by flags. <...>

Returns the result of executing the code as a Python object, or NULL if an exception was raised.

 

So far, your 'fun' variable seems empty and returns as 'none'

 

If you don't want to delve into Python / Python C API you could just to use TPythonDelphiVar according to pyscripter's  advice:

declare a name for the python scope variable https://github.com/pyscripter/python4delphi/blob/master/Demos/Demo03/Unit1.dfm#L137

and use it in your script https://github.com/pyscripter/python4delphi/blob/master/Demos/Demo03/Unit1.dfm#L42 

 

Hope, this helps

Share this post


Link to post

Sorry, I misunderstood your statement.

 

did not notice that this code is different from the original specified in the question

 

In this case, you just do not have an assignment to the PythonDelphiVar1 variable in Python script there and naturally you get none.

 

But of course it's a matter of taste which approach to use.

Share this post


Link to post

This is the second post where you are simply being rude and offending everyone around you.

 

I learned it a long time ago but it's not clearly documented, but a solution can be found by hovering over a user's name:

 

image.png.388ee4ad4e524824e3fa8b97cf94e759.png

  • Haha 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×