Calling a Python function from within a C# environment

Hi, does anyone managed to call a Python lambda function from inside a C# component?
I already confirmed a C# lambda function wrapped by a Func<> can be simply called from within a Python environment, but cannot find the way to do the other way around.

The senario is like this.
I have a code written in Python but it turns out I need to salvage all of them to a C# node.
However there is a function too complicated and I don’t want to rewrite it. So I’m thinking to rewrite the main code in C# but call a function coded in a Python node from within a C# node.

Thanks!

Haven’t tried it before, but it looks doable writing a wrapper for the python class.

You can execute a python script with the console in C# and then retrieve the result to the component, using the process class, but you have to format the result because console only return strings. I wouldn’t use IronPython.

  System.Diagnostics.Process proc = new System.Diagnostics.Process
  {
    StartInfo = new System.Diagnostics.ProcessStartInfo
    {
      FileName = @"C:\windows\system32\cmd.exe",
      Arguments = @"/c C:\Users\python.exe C:\Users\xxxx.py ",
      UseShellExecute = false,

      RedirectStandardOutput = true,
      RedirectStandardError = true,
      CreateNoWindow = true
      }
    };

proc.Start();

string result = proc.StandardOutput.ReadToEnd();

RunPython.gh (2.5 KB)

Hi, sorry my explanation was not clear enough.
What I’m trying to do is to pull out a lambda function (can be a regular function as well) from a Python node and catch it by a C# node and execute the function.
The general discussion of running a Python code from inside a C# code is too tricky. I’m taking advantage from the fact that, in GH environment, you can directly connect Python and C# nodes and pass some objects, and since those objects are .NET objects, there should be a way.

Python node

a=lambda x:x*2

Output:a

C# node

Print(F(10d))

Input F (connected to “a” of the Python node)

Amazingly the below works without any tick(calling a C# function from inside a Python node)
C# node

A=new Func<double,double>((x)=>x*2);

Output:A

python node

print f(10.0)

Input f (connected to the “A” of the C# node)

Also, sorry for the confusion, this guys is the same person as the first post. I couldn’t find a way to change the account and I have to PCs tied to different accounts.

This works.

This doesn’t work.

In the first image, A is a function. You are therefore passing the function with the lambda in it to the python.

In the second image, you are declaring a as the result of the lambda function as compared to being the function.

You can do something similar by declaring the variable a as a function:


But I’m not really sure how to get the function to be called.
Only way I think this might work is:
https://documentation.help/IronPython/getting_started.html
where engine.createscriptsource (CodeObject content) is used to set the function as the code.
I can’t confirm as I’m not familiar with the c# code component in grasshopper.

Otherwise it would be easier to just wrap the function as a class in python and pass the class to the c#.
You then set all the arguements in C# and then call the function to run on that class and get the result back out.

Hello, I believe

a=lambda x:x*2

and

def func(x):
    return x*2
a=func

are the same.)

The problem is that C# is a static typing language. So you need to figure out what class is actually wrapping those functions internally in Python, and declare the class types accurately in C#, which I think is too much pain and headache. The reason the other way around was possible is that Python is a dynamic typing language.

Actually I found a solution online. It seems like it is possible to wrap a function by C# Func<> or Action<>.

import clr
from System import Func
import System
import System.Collections.Generic
def f(x):
    return x*2
a=Func[System.Double,System.Double](f)

this a can be passed to a C# node, then cast to Func<double,double> safely, and finally can be called simply by F(x);

Yey! Thanks for the help!

1 Like

I don’t use lambda notation in python, so didn’t know that.

Glad your problem is solved though.