softtouch 9 Posted 17 hours ago (edited) When you access a Python variable or constant through MainModule.varname, Python4Delphi retrieves the value and caches it I think. Subsequent executions of Python scripts, even if they don't define the same variable, won't automatically clear this cached value and MainModule.varname retun the previous value. is there any function that clears this cached values without reinitializing the python engine? Example: python1.py: MYVALUE = 'test' Delphi: python.ExecFile(python1.py); s:=MainModule.MYVALUE; // This return 'test' python.ExecFile(python2.py); // This does not have this constant/variable in it s:=MainModule.MYVALUE; // This return again 'test' Edited 17 hours ago by softtouch Share this post Link to post
pyscripter 728 Posted 12 hours ago (edited) Indeed. Python variables are reference counted. As long as you keep a reference the python object it refers to is kept alive. When you have a statement like: var s:Variant :=MainModule.MYVALUE s is a custom variant that stores the python reference. The variable will be dereferenced, when s goes out of scope or you explicitly clear s (VarClear(s)). Edited 12 hours ago by pyscripter Share this post Link to post
softtouch 9 Posted 5 hours ago I still encounter the problem. Python script python1.py: VALUE = 'testing' Python script python1.py: MYVAL = 'something else' Delphi: var val:variant; GetPythonEngine.ExecFile('python1.py'); val := MainModule.VALUE; // val contains 'testing' varclear(val); // val shows "unassigned" GetPythonEngine.ExecFile('python2.py'); val := MainModule.VALUE; // val contains 'testing' again, even it does not exist in python2.py. Share this post Link to post
pyscripter 728 Posted 5 hours ago (edited) 41 minutes ago, softtouch said: val contains 'testing' again, even it does not exist in python2.py. Of course it does. What you are doing is like running the following python script: exec("a = 1; print(a)") exec("b = 1; print(a)") a is created in the first statement and still exists when the second statement is executed. but if you do exec("a = 1; print(a)", {}, {}) exec("b = 1; print(a)", {}, {}) then the second statement raises an error. ExecFile has the following signature: procedure ExecFile(const FileName: string; locals: PPyObject = nil; globals: PPyObject = nil); If you provide no arguments for locals and globals, the code is executed in the namespace of the __main__ module. If you do not want this to happen then you should provide empty dictionaries as arguments for the locals and globals parameters (or just the locals). But then MainModule.VALUE will raise an error. Example code (not tested): var Py := GetPythonEngine; var NewDict := NewPythonDict; Py.ExecFile('python1.py', ExtractPythonObjectFrom(NewDict)); var val := NewDict.GetItem("VALUE"); NewDict := NewPythonDict; Py.ExecFile('python2.py', ExtractPythonObject(NewDict)); val := NewDict.GetItem("VALUE"); // will raise an error since VALUE does not exist VarClear(NewDict); Edited 4 hours ago by pyscripter Share this post Link to post