I too am working (slowly) on adding pythonnet as scripting environment for a 
.NET application.  When investigating this I wrote a VS project that tested all 
the assumptions I was making about how the interface worked.  That is available 
on GitHub at:  https://github.com/tomunger/pythonnet.embedingtest

Below is the method I use to load a module.  Note that I don’t import the 
module but execute it in the PyScope.

Tom


                                private PyScope LoadModule(string name, string 
fileName, Dictionary<string, object> globals)
                                {
                                                PyScope scope = null;
                                                using (Py.GIL())
                                                {
                                                                // Create a new 
scope
                                                                scope = 
Py.CreateScope(name);

                                                                // Assign any 
globals.
                                                                if (globals != 
null)
                                                                {
                                                                                
foreach (string gname in globals.Keys)
                                                                                
                scope.Set(gname, globals[gname]);
                                                                }

                                                                // Load python 
code, compile, then execute it in the scope.
                                                                string 
scriptText = File.ReadAllText(fileName);
                                                                PyObject code = 
PythonEngine.Compile(scriptText, fileName);
                                                                dynamic r = 
scope.Execute(code);
                                                }
                                                return scope;
                                }

________________________________
From: PythonDotNet <pythondotnet-bounces+tunger=mitem....@python.org> on behalf 
of Mohamed Koubaa <mohamed.kou...@ansys.com>
Sent: Monday, September 24, 2018 7:03:52 AM
To: pythondotnet@python.org
Cc: hbtmdx...@126.com
Subject: Re: [Python.NET] Using PyScope to set variables I can use in imported 
scripts

Steve,

My organization is interested in migrating from IronPython to PythonNet so I'll 
add my two cents.  We do this:

1.  (during startup) Run a short python file which imports some .NET namespaces 
into a scope
2.  (during startup) Add some variables to that scope (globals which give 
scripts access to our data model)
3.  (at arbitrary times later) Run python code in the above scope so that there 
isn't a need to import the namespaces or discover the data model

Thanks,
Mohamed Koubaa
ANSYS Inc

On Mon, Sep 24, 2018 at 8:59 AM Luke, Steve 
<steve.l...@moldev.com<mailto:steve.l...@moldev.com>> wrote:

Yes, I did.  All the unit tests for PyScope use the Eval(), Exec(), or 
Execute() functions to get code to execute in the PyScope.  They don't use 
Import the way I had been (hoping to do).


I am probably using it differently than intended/expected.  I am importing a 
script into the scope and expect to be able to inject variables into the 
imported module.  That doesn't seem to be what PyScope is used for.  Instead, 
PyScope seems to be a container for the code and variables like the __main__ 
scope that gets created when running Python from the command prompt.  It looks 
like when you Import it creates a new nested scope which doesn't have access to 
the scope created by PyScope.  I had expected it to work as PyScope was the 
scope in which the Imported code would be executed, not the parent scope.  I 
think the intended way to use PyScope and access the variables it holds is to 
pass the code in as Strings using Exec().


I think the right thing to do is:

1) Set variables in PyScope

2) Add the path to the script to the sys.path

3) Read the contents of the script file into a string

4) Use the PyScope to Exec() Execute() or Eval() as appropriate


This works it is just not the same as what I was used to with IronPython (which 
is fine if that is really how it is intended to be used).


Steve

________________________________
From: Denis Akhiyarov 
<denis.akhiya...@gmail.com<mailto:denis.akhiya...@gmail.com>>
Sent: Monday, September 24, 2018 9:36:19 AM
To: Luke, Steve; A list for users and developers of Python for .NET
Cc: ywg
Subject: Re: [Python.NET] Using PyScope to set variables I can use in imported 
scripts

I copied Wenguang Yang (@yagweb), who developed PyScope.

Steve, did you look at the unit tests for PyScope?

Thanks,
Denis

On Mon, Sep 24, 2018 at 8:28 AM Luke, Steve 
<steve.l...@moldev.com<mailto:steve.l...@moldev.com>> wrote:

I am new to Python.Net and trying to convert an application that used 
IronPython to embed a Python environment into a .Net application and allow the 
user to run Python scripts inside our application.  The part that embeds the 
Python environment is VB.Net (but could be C# if that would be better).


I am running into problems setting variables in the scope such that they can be 
used in the Python scripts we call.  I keep getting an error: NameError: global 
name 'Bridge' is not defined.


This is the VB code I am trying to use:

        PythonEngine.Initialize()

        Using (Py.GIL())
            Dim moduleName As String = "PrintToBridge"
            Dim pythonCommandLine As String = "Not used yet"

            Dim scope As PyScope = Py.CreateScope()
            Try
                scope.Set("Bridge", bridge)
                scope.Set("SetupParams", cmdLine)

                Dim script As Object = scope.Import(moduleName)
                bridge.mm.PrintMsg("Scope has Bridge:" + 
Str(scope.Contains("Bridge")))
                script.Startup(pythonCommandLine)
            Finally
                scope.Dispose()
            End Try
        End Using

The Python script:

def Startup(param):
    Bridge.mm.PrintMsg('Startup called')

def Docommand(param):
    Bridge.mm.PrintMsg('docommand called')

def Shutdown():
    Bridge.mm.PrintMsg('Shutdown called')



How can I set a variable such that it would be recognized by the called Python 
script?  Importing the script works, I can force python-y things to happen.  
And the check to see if the object I want is in scope returns true.  But it 
still isn't available in Python.


I have tried scope.Eval(moduleName + ".Startup('" + pythonCommandLine + "')") 
and Exec() with locals:

                Dim locals As PyDict = New PyDict()
                locals.SetItem("Bridge".ToPython(), bridge.ToPython())
                scope.Exec(moduleName + ".Startup('" + pythonCommandLine + 
"')", locals)


All with the same effect.  Any ideas on how to get set variables so scripts can 
gain access to them?


Thanks,

Steve


Please be advised that this email may contain confidential information. If you 
are not the intended recipient, please notify us by email by replying to the 
sender and delete this message. The sender disclaims that the content of this 
email constitutes an offer to enter into, or the acceptance of, any agreement; 
provided that the foregoing does not invalidate the binding effect of any 
digital or other electronic reproduction of a manual signature that is included 
in any attachment.
_________________________________________________
Python.NET mailing list - 
PythonDotNet@python.org<mailto:PythonDotNet@python.org>
https://mail.python.org/mailman/listinfo/pythondotnet<https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.python.org_mailman_listinfo_pythondotnet&d=DwMFaQ&c=9mghv0deYPYDGP-W745IEdQLV1kHpn4XJRvR6xMRXtA&r=XBqO7p7APNCVKpdDR1v4BCUJqDo0CwXYsXZCFrPPxqg&m=9mSyhuL5_TpZgYqhGupLEDwQ8mpZrrmrs3zDjcmbhHk&s=vkTiivd8fJevlpD6Kn7hi5R5vSunthrCXQwRwuD3xYo&e=>
Please be advised that this email may contain confidential information. If you 
are not the intended recipient, please notify us by email by replying to the 
sender and delete this message. The sender disclaims that the content of this 
email constitutes an offer to enter into, or the acceptance of, any agreement; 
provided that the foregoing does not invalidate the binding effect of any 
digital or other electronic reproduction of a manual signature that is included 
in any attachment.
_________________________________________________
Python.NET mailing list - 
PythonDotNet@python.org<mailto:PythonDotNet@python.org>
https://mail.python.org/mailman/listinfo/pythondotnet
_________________________________________________
Python.NET mailing list - PythonDotNet@python.org
https://mail.python.org/mailman/listinfo/pythondotnet

Reply via email to