mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 04:50:17 +00:00
some fix
This commit is contained in:
parent
1bda712825
commit
f7b0abff5a
@ -1,185 +0,0 @@
|
|||||||
---
|
|
||||||
label: Bindings
|
|
||||||
icon: dot
|
|
||||||
order: 10
|
|
||||||
---
|
|
||||||
|
|
||||||
Bindings are methods and variables that are defined in C# and can be accessed from Python.
|
|
||||||
We provide two types of bindings: static bindings and dynamic bindings.
|
|
||||||
|
|
||||||
## Static Bindings
|
|
||||||
|
|
||||||
Static bindings wrap a C# class or struct and expose its methods and variables to Python.
|
|
||||||
This is the most common way to define bindings.
|
|
||||||
Static bindings are initialized at compile time.
|
|
||||||
|
|
||||||
### Manual Static Bindings
|
|
||||||
|
|
||||||
Manual static bindings directly create a Python equivalent of `def f(a, b, *args)` in C#.
|
|
||||||
To use it, you need to create a class that inherits from `PyTypeObject`.
|
|
||||||
And implement some abstract methods to specify the name and type of the Python type.
|
|
||||||
For example, to make `UnityEngine.Vector2` available in Python, you can write a `PyVector2Type`
|
|
||||||
class like the following.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public class PyVector2Type: PyTypeObject{
|
|
||||||
// The name of the type in Python
|
|
||||||
public override string Name => "Vector2";
|
|
||||||
|
|
||||||
// The corresponding C# type
|
|
||||||
public override System.Type CSType => typeof(Vector2);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Next, you need to define each method and variable to be exposed to Python,
|
|
||||||
by using `[PythonBinding]` attribute.
|
|
||||||
|
|
||||||
!!!
|
|
||||||
We assume that you have necessary knowledge about
|
|
||||||
[Python's data model](https://docs.python.org/3/reference/datamodel.html).
|
|
||||||
Such as magic methods, `__new__`, `__init__`, `__add__` and so on.
|
|
||||||
Otherwise, you may have trouble understanding the following code.
|
|
||||||
!!!
|
|
||||||
|
|
||||||
Let's define a magic method `__add__`, it is used to implement the `+` operator in Python.
|
|
||||||
With `__add__`, `Vector2` object in Python can be added with another `Vector2` object.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public class PyVector2Type: PyTypeObject{
|
|
||||||
public override string Name => "Vector2";
|
|
||||||
public override System.Type CSType => typeof(Vector2);
|
|
||||||
|
|
||||||
[PythonBinding]
|
|
||||||
public object __add__(Vector2 self, object other){
|
|
||||||
// If the other object is not a Vector2, return NotImplemented
|
|
||||||
if(!(other is Vector2)) return VM.NotImplemented;
|
|
||||||
// Otherwise, return the result of addition
|
|
||||||
return self + (Vector2)other;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
This is easy to understand.
|
|
||||||
Let's see another example, `__mul__`, it is used to implement the `*` operator in Python.
|
|
||||||
`Vector2` object in C# can be multiplied with a `float` object in Python.
|
|
||||||
The following code shows this usage.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
Vector2 a = new Vector2(1, 2);
|
|
||||||
Vector2 b = a * 2.0f;
|
|
||||||
Vector2 c = 2.0f * a;
|
|
||||||
```
|
|
||||||
|
|
||||||
As you can see, things are slightly different from `__add__`.
|
|
||||||
Because the `float` operand can be on the left or right side of the `*` operator.
|
|
||||||
In this case, you need to define `__mul__` and `__rmul__` at the same time.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public class PyVector2Type: PyTypeObject{
|
|
||||||
public override string Name => "Vector2";
|
|
||||||
public override System.Type CSType => typeof(Vector2);
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
[PythonBinding]
|
|
||||||
public object __mul__(Vector2 self, object other){
|
|
||||||
if(!(other is float)) return VM.NotImplemented;
|
|
||||||
return self * (float)other;
|
|
||||||
}
|
|
||||||
|
|
||||||
[PythonBinding]
|
|
||||||
public object __rmul__(Vector2 self, object other){
|
|
||||||
if(!(other is float)) return VM.NotImplemented;
|
|
||||||
return self * (float)other;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally, let's implement the constructor of `Vector2`.
|
|
||||||
`__new__` magic method must be defined.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public class PyVector2Type: PyTypeObject{
|
|
||||||
public override string Name => "Vector2";
|
|
||||||
public override System.Type CSType => typeof(Vector2);
|
|
||||||
|
|
||||||
[PythonBinding]
|
|
||||||
public object __new__(PyTypeObject cls, params object[] args){
|
|
||||||
if(args.Length == 0) return new Vector2();
|
|
||||||
if(args.Length == 2){
|
|
||||||
float x = vm.PyCast<float>(args[0]);
|
|
||||||
float y = vm.PyCast<float>(args[1]);
|
|
||||||
return new Vector2(x, y);
|
|
||||||
}
|
|
||||||
vm.TypeError("Vector2.__new__ takes 0 or 2 arguments");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Here we use `params object[] args` to tell the bindings that the constructor can take any number of arguments.
|
|
||||||
It is equivalent to `def __new__(cls, *args)` in Python.
|
|
||||||
Note that Python does not support method overloading.
|
|
||||||
So we manually check the number of arguments and their types to determine which constructor to call.
|
|
||||||
|
|
||||||
For fields, we can form a Python property by defining a getter and a setter.
|
|
||||||
By using `[PythonBinding(BindingType.Getter)]` and `[PythonBinding(BindingType.Setter)]` attributes.
|
|
||||||
|
|
||||||
!!!
|
|
||||||
However, this has certain limitations for value types. Because `Vector2` is a struct, it is passed by value.
|
|
||||||
So our setter will not be able to modify the original `Vector2` object.
|
|
||||||
!!!
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
public class PyVector2Type: PyTypeObject{
|
|
||||||
public override string Name => "Vector2";
|
|
||||||
public override System.Type CSType => typeof(Vector2);
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Getter)]
|
|
||||||
public object x(Vector2 self) => self.x;
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Setter)]
|
|
||||||
public void x(Vector2 self, object value) => self.x = vm.PyCast<float>(value);
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Getter)]
|
|
||||||
public object y(Vector2 self) => self.y;
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Setter)]
|
|
||||||
public void y(Vector2 self, object value) => self.y = vm.PyCast<float>(value);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you have done all the above, you must register the type to the VM.
|
|
||||||
Here we set it into `builtins` module, so that it can be accessed from anywhere.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
vm.RegisterType(new PyVector2Type(), vm.builtins);
|
|
||||||
```
|
|
||||||
|
|
||||||
To summarize, manual static bindings provide detailed control for exposing a C# class to Python.
|
|
||||||
You decide which methods and variables to expose, and how to expose them.
|
|
||||||
This is our recommended way to define bindings. Also it is the most performant way.
|
|
||||||
|
|
||||||
### Automatic Static Bindings
|
|
||||||
|
|
||||||
Automatic static bindings use C# reflection to automatically generate bindings for a C# class.
|
|
||||||
It is convenient for testing and prototyping, but it is slow and unsafe since the user can access any member of the class.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
vm.RegisterAutoType<Vector2>(vm.builtins);
|
|
||||||
```
|
|
||||||
|
|
||||||
That's all you need to do. The `RegisterAutoType<T>` method will automatically generate bindings for `Vector2`.
|
|
||||||
|
|
||||||
|
|
||||||
## Dynamic Bindings
|
|
||||||
|
|
||||||
Dynamic bindings allow you to add a single C# lambda function to an object at runtime.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
delegate object NativeFuncC(VM vm, object[] args);
|
|
||||||
```
|
|
||||||
|
|
||||||
+ `CSharpLambda BindFunc(PyObject obj, string name, int argc, NativeFuncC f)`
|
|
||||||
|
|
||||||
It is similar to `bind_func` in [C++ API](../bindings/).
|
|
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
label: Python console
|
|
||||||
icon: dot
|
|
||||||
order: 5
|
|
||||||
---
|
|
||||||
|
|
||||||
You can open the Python console in Unity by clicking the `Window/Python Console` menu item.
|
|
||||||
|
|
||||||
By default, the console creates a unmodified `VM` instance to execute your code.
|
|
||||||
You may want to provide an enhanced `VM` instance for the console in Unity Editor.
|
|
||||||
For example, adding some class bindings in `UnityEngine` namespace.
|
|
||||||
|
|
||||||
To do this, you need to create a class derived from `VM` and put it in `Assets/Editor/` folder.
|
|
||||||
By adding `[EditorVM]` attribute to the class,
|
|
||||||
the console will use it instead of the default `VM` instance.
|
|
||||||
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
using PocketPython;
|
|
||||||
|
|
||||||
[EditorVM] // this attribute is required
|
|
||||||
public class EnhancedVM: VM{
|
|
||||||
public EnhancedVM() {
|
|
||||||
RegisterAutoType<GameObject>(builtins);
|
|
||||||
RegisterAutoType<Transform>(builtins);
|
|
||||||
RegisterAutoType<Vector2>(builtins);
|
|
||||||
RegisterAutoType<Vector3>(builtins);
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
@ -1,166 +0,0 @@
|
|||||||
---
|
|
||||||
label: Examples
|
|
||||||
icon: dot
|
|
||||||
order: 4
|
|
||||||
---
|
|
||||||
|
|
||||||
See `Assets/PocketPython/Examples` after you import the plugin.
|
|
||||||
|
|
||||||
|
|
||||||
### Primes Example
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace PocketPython
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Example of using PocketPython to find prime numbers.
|
|
||||||
/// </summary>
|
|
||||||
public class PrimesExample : MonoBehaviour
|
|
||||||
{
|
|
||||||
// Start is called before the first frame update
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
var vm = new VM();
|
|
||||||
const string source = @"
|
|
||||||
def is_prime(x):
|
|
||||||
if x < 2:
|
|
||||||
return False
|
|
||||||
for i in range(2, x):
|
|
||||||
if x % i == 0:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
primes = [i for i in range(2, 20) if is_prime(i)]
|
|
||||||
print(primes)
|
|
||||||
";
|
|
||||||
CodeObject code = vm.Compile(source, "main.py", CompileMode.EXEC_MODE);
|
|
||||||
vm.Exec(code); // [2, 3, 5, 7, 11, 13, 17, 19]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Vector2 Example
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace PocketPython
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Example of making UnityEngine.Vector2 available to Python.
|
|
||||||
/// </summary>
|
|
||||||
public class Vector2Example : MonoBehaviour
|
|
||||||
{
|
|
||||||
// Start is called before the first frame update
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
var vm = new VM();
|
|
||||||
// register UnityEngine.Vector2 type into the builtins module
|
|
||||||
vm.RegisterAutoType<Vector2>(vm.builtins);
|
|
||||||
|
|
||||||
vm.Exec("print(Vector2)", "main.py"); // <class 'Vector2'>
|
|
||||||
vm.Exec("v = Vector2(1, 2)", "main.py");
|
|
||||||
vm.Exec("print(v)", "main.py"); // (1.0, 2.0)
|
|
||||||
vm.Exec("print(v.x)", "main.py"); // 1.0
|
|
||||||
vm.Exec("print(v.y)", "main.py"); // 2.0
|
|
||||||
vm.Exec("print(v.magnitude)", "main.py"); // 2.236068
|
|
||||||
vm.Exec("print(v.normalized)", "main.py"); // (0.4472136, 0.8944272)
|
|
||||||
vm.Exec("print(Vector2.Dot(v, v))", "main.py"); // 5.0
|
|
||||||
vm.Exec("print(Vector2.get_up())", "main.py"); // (0.0, 1.0)
|
|
||||||
|
|
||||||
Vector2 v = (Vector2)vm.Eval("Vector2(3, 4) + v");
|
|
||||||
Debug.Log(v); // (4.0, 6.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### MyClass Example
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using UnityEngine;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace PocketPython
|
|
||||||
{
|
|
||||||
|
|
||||||
public class MyClass
|
|
||||||
{
|
|
||||||
public string title;
|
|
||||||
public string msg;
|
|
||||||
|
|
||||||
public void Print()
|
|
||||||
{
|
|
||||||
Debug.Log(title + ": " + msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PyMyclassType : PyTypeObject
|
|
||||||
{
|
|
||||||
public override string Name => "my_class";
|
|
||||||
public override Type CSType => typeof(MyClass);
|
|
||||||
|
|
||||||
[PythonBinding]
|
|
||||||
public object __new__(PyTypeObject cls)
|
|
||||||
{
|
|
||||||
return new MyClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Getter)]
|
|
||||||
public string title(MyClass value) => value.title;
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Getter)]
|
|
||||||
public string msg(MyClass value) => value.msg;
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Setter)]
|
|
||||||
public void title(MyClass value, string title) => value.title = title;
|
|
||||||
|
|
||||||
[PythonBinding(BindingType.Setter)]
|
|
||||||
public void msg(MyClass value, string msg) => value.msg = msg;
|
|
||||||
|
|
||||||
[PythonBinding]
|
|
||||||
public void print(MyClass value) => value.Print();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Example of binding a custom C# class to Python.
|
|
||||||
/// </summary>
|
|
||||||
public class MyClassExample : MonoBehaviour
|
|
||||||
{
|
|
||||||
// Start is called before the first frame update
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
var vm = new VM();
|
|
||||||
|
|
||||||
// register MyClass type into the builtins module
|
|
||||||
vm.RegisterType(new PyMyclassType(), vm.builtins);
|
|
||||||
|
|
||||||
vm.Exec("print(my_class)", "main.py"); // <class 'my_class'>
|
|
||||||
vm.Exec("c = my_class()", "main.py");
|
|
||||||
vm.Exec("c.title = 'Greeting'", "main.py");
|
|
||||||
vm.Exec("c.msg = 'Hello, world!'", "main.py");
|
|
||||||
|
|
||||||
string title = vm.Eval("c.title").ToString();
|
|
||||||
string msg = vm.Eval("c.msg").ToString();
|
|
||||||
|
|
||||||
Debug.Log(title + ": " + msg); // Greeting: Hello, world!
|
|
||||||
|
|
||||||
vm.Exec("c.print()", "main.py"); // Greeting: Hello, world!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
label: Unity Plugin
|
|
||||||
icon: code
|
|
||||||
order: 0
|
|
@ -1,82 +0,0 @@
|
|||||||
---
|
|
||||||
label: Introduction
|
|
||||||
icon: dot
|
|
||||||
order: 30
|
|
||||||
---
|
|
||||||
|
|
||||||
# Welcome to PocketPython
|
|
||||||
|
|
||||||
PocketPython is a C# plugin that allows you to do Python scripting in Unity. It provides a sandboxed Python environment, which adds dynamic capabilities to your game, which can be used for dynamic game logic, modding, hot fixing, and more.
|
|
||||||
|
|
||||||
The virtual machine is written in pure C#, which means you can fully control the internal state of the Python interpreter.
|
|
||||||
|
|
||||||
!!!
|
|
||||||
PocketPython is designed for game scripting, not for scientific computing.
|
|
||||||
You cannot use it to run NumPy, OpenCV, or any other CPython extension modules.
|
|
||||||
!!!
|
|
||||||
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
### Python 3.x Syntax
|
|
||||||
|
|
||||||
PocketPython uses [pocketpy](https://github.com/pocketpy/pocketpy)
|
|
||||||
as frontend to parse and compile Python source code.
|
|
||||||
It supports most of the Python 3.x syntax.
|
|
||||||
|
|
||||||
The following table shows a feature comparison of PocketPython
|
|
||||||
with respect to the original [pocketpy](https://github.com/pocketpy/pocketpy).
|
|
||||||
The features marked with `YES` are supported, and the features marked with `NO` are not supported.
|
|
||||||
|
|
||||||
| Name | Example | Cpp | Unity |
|
|
||||||
| --------------- | ------------------------------- | --------- | --- |
|
|
||||||
| If Else | `if..else..elif` | YES | YES |
|
|
||||||
| Loop | `for/while/break/continue` | YES | YES |
|
|
||||||
| Function | `def f(x,*args,y=1):` | YES | YES |
|
|
||||||
| Subclass | `class A(B):` | YES | YES |
|
|
||||||
| List | `[1, 2, 'a']` | YES | YES |
|
|
||||||
| ListComp | `[i for i in range(5)]` | YES | YES |
|
|
||||||
| Slice | `a[1:2], a[:2], a[1:]` | YES | YES |
|
|
||||||
| Tuple | `(1, 2, 'a')` | YES | YES |
|
|
||||||
| Dict | `{'a': 1, 'b': 2}` | YES | YES |
|
|
||||||
| F-String | `f'value is {x}'` | YES | YES |
|
|
||||||
| Unpacking | `a, b = 1, 2` | YES | YES |
|
|
||||||
| Star Unpacking | `a, *b = [1, 2, 3]` | YES | YES |
|
|
||||||
| Exception | `raise/try..catch` | YES | NO |
|
|
||||||
| Dynamic Code | `eval()/exec()` | YES | YES |
|
|
||||||
| Reflection | `hasattr()/getattr()/setattr()` | YES | YES |
|
|
||||||
| Import | `import/from..import` | YES | YES |
|
|
||||||
| Context Block | `with <expr> as <id>:` | YES | NO |
|
|
||||||
| Type Annotation | `def f(a:int, b:float=1)` | YES | YES |
|
|
||||||
| Generator | `yield i` | YES | NO |
|
|
||||||
| Decorator | `@cache` | YES | YES |
|
|
||||||
|
|
||||||
### Sandboxed Python Environment
|
|
||||||
|
|
||||||
PocketPython provides a sandboxed Python environment.
|
|
||||||
All python code is executed in a C# virtual machine.
|
|
||||||
The user cannot access the file system, network, or any other resources of the host machine.
|
|
||||||
|
|
||||||
### Seamless Interop with C#
|
|
||||||
|
|
||||||
PocketPython uses `object` in C# to represent dynamic typed Python objects.
|
|
||||||
Most of the basic Python types correspond to a C# type,
|
|
||||||
which means passing arguments between C# and Python is extremely easy and intuitive.
|
|
||||||
|
|
||||||
| Python Type | C# Type |
|
|
||||||
| ----------- | ------- |
|
|
||||||
| `None` | `NoneType` |
|
|
||||||
| `object` | `System.Object` |
|
|
||||||
| `bool` | `System.Boolean` |
|
|
||||||
| `int` | `System.Int32` |
|
|
||||||
| `float` | `System.Single` |
|
|
||||||
| `str` | `System.String` |
|
|
||||||
| `tuple` | `System.Object[]` |
|
|
||||||
| `list` | `System.Collections.Generic.List<object>` |
|
|
||||||
| `dict` | `System.Collections.Generic.Dictionary<PyDictKey, object>` |
|
|
||||||
| ... | ... |
|
|
||||||
|
|
||||||
### Python Console in Editor
|
|
||||||
|
|
||||||
PocketPython provides a Python console in Unity editor,
|
|
||||||
which allows you to do quick debugging and testing.
|
|
153
docs/unity/vm.md
153
docs/unity/vm.md
@ -1,153 +0,0 @@
|
|||||||
---
|
|
||||||
label: Virtual machine
|
|
||||||
icon: dot
|
|
||||||
order: 20
|
|
||||||
---
|
|
||||||
|
|
||||||
The `VM` class provides a sandboxed Python environment and a set of APIs for interacting with it.
|
|
||||||
Using the namespace `PocketPython` before any operations.
|
|
||||||
|
|
||||||
```csharp
|
|
||||||
using PocketPython;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Construction
|
|
||||||
|
|
||||||
+ `VM()`
|
|
||||||
|
|
||||||
Create a new Python virtual machine.
|
|
||||||
|
|
||||||
### Code Execution
|
|
||||||
|
|
||||||
+ `CodeObject Compile(string source, string filename, CompileMode mode)`
|
|
||||||
|
|
||||||
Compile Python source code into a `CodeObject` that can be executed later.
|
|
||||||
The `filename` parameter is used for error reporting, you can set it to `main.py` if you don't need it.
|
|
||||||
The `mode` parameter specifies the compile mode, see [CompileMode](../quick-start/exec/#compile-mode) for details.
|
|
||||||
|
|
||||||
+ `object Exec(CodeObject co, PyModule mod = null)`
|
|
||||||
|
|
||||||
Execute a `CodeObject` in the given module.
|
|
||||||
The `mod` parameter specifies the module in which the code will be executed.
|
|
||||||
If it is `null`, the code will be executed in the main module.
|
|
||||||
|
|
||||||
+ `object Exec(string source, string filename, CompileMode mode = CompileMode.EXEC_MODE, PyModule mod = null)`
|
|
||||||
|
|
||||||
Compile and execute Python source code in the given module. It is equivalent to `Exec(Compile(source, filename, mode), mod)`.
|
|
||||||
|
|
||||||
+ `object Eval(string source, PyModule mod = null)`
|
|
||||||
|
|
||||||
Evaluate an expression in the given module.
|
|
||||||
|
|
||||||
+ `object Call(object callable, object[] args, Dictionary<string, object> kwargs)`
|
|
||||||
|
|
||||||
Call a Python callable object with the given arguments and keyword arguments. It is equivalent to `callable(*args, **kwargs)` in Python.
|
|
||||||
|
|
||||||
+ `object CallMethod(object obj, string name, params object[] args)`
|
|
||||||
|
|
||||||
Call a method of a Python object with the given arguments. It is equivalent to `obj.name(*args)` in Python.
|
|
||||||
|
|
||||||
|
|
||||||
### Attribute Access
|
|
||||||
|
|
||||||
+ `object GetAttr(object obj, string name, bool throwErr = true)`
|
|
||||||
|
|
||||||
Get an attribute of a Python object. It is equivalent to `obj.name` in Python.
|
|
||||||
If `throwErr` is `true`, it will throw an exception if the attribute does not exist.
|
|
||||||
Otherwise, it will return `null`.
|
|
||||||
|
|
||||||
+ `NoneType SetAttr(object obj, string name, object value)`
|
|
||||||
|
|
||||||
Set an attribute of a Python object. It is equivalent to `obj.name = value` in Python.
|
|
||||||
|
|
||||||
+ `bool HasAttr(object obj, string name)`
|
|
||||||
|
|
||||||
Check if a Python object has the given attribute. It is equivalent to `hasattr(obj, name)` in Python.
|
|
||||||
|
|
||||||
### Module Access
|
|
||||||
|
|
||||||
+ `Dictionary<string, PyModule> modules`
|
|
||||||
|
|
||||||
A dictionary that maps module names to `PyModule` objects.
|
|
||||||
You can use it to access the modules that have been imported.
|
|
||||||
|
|
||||||
+ `Dictionary<string, string> lazyModules`
|
|
||||||
|
|
||||||
A dictionary stores all unimported modules. You can add Python source into this dictionary.
|
|
||||||
It will be initialized and moved to `modules` when it is first imported.
|
|
||||||
|
|
||||||
+ `PyModule NewModule(string name)`
|
|
||||||
|
|
||||||
Create a new module with the given name at runtime. The module will be added to `modules` automatically.
|
|
||||||
|
|
||||||
+ `PyModule PyImport(string name)`
|
|
||||||
|
|
||||||
Import a Python module. It is equivalent to `import name` in Python. It first checks if the module has been imported, if not, it will try to load the module from `lazyModules`.
|
|
||||||
|
|
||||||
|
|
||||||
### Type Conversion
|
|
||||||
|
|
||||||
+ `T PyCast<T>(object obj)`
|
|
||||||
|
|
||||||
Convert a Python object to a C# object. It is equivalent to `obj as T` in C#.
|
|
||||||
Raise `TypeError` if the conversion fails.
|
|
||||||
|
|
||||||
+ `bool IsInstance(object obj, PyTypeObject type)`
|
|
||||||
|
|
||||||
Check if a Python object is an instance of the given type. It is equivalent to `isinstance(obj, type)` in Python.
|
|
||||||
|
|
||||||
+ `void CheckType<T>(object t)`
|
|
||||||
|
|
||||||
Check if `t is T`. Raise `TypeError` if the check fails.
|
|
||||||
|
|
||||||
+ `bool PyEquals(object lhs, object rhs)`
|
|
||||||
|
|
||||||
Check if two Python objects are equal. It is equivalent to `lhs == rhs` in Python. This is different from `==` or `object.ReferenceEquals` in C#. You should always use this method to compare Python objects.
|
|
||||||
|
|
||||||
+ `object PyIter(object obj)`
|
|
||||||
|
|
||||||
Get an iterator of a Python object. It is equivalent to `iter(obj)` in Python.
|
|
||||||
|
|
||||||
+ `object PyNext(object obj)`
|
|
||||||
|
|
||||||
Get the next element of a Python iterator. It is equivalent to `next(obj)` in Python.
|
|
||||||
|
|
||||||
+ `bool PyBool(object obj)`
|
|
||||||
|
|
||||||
Convert a Python object to a boolean value. It is equivalent to `bool(obj)` in Python.
|
|
||||||
|
|
||||||
+ `string PyStr(object obj)`
|
|
||||||
|
|
||||||
Convert a Python object to a string. It is equivalent to `str(obj)` in Python.
|
|
||||||
|
|
||||||
+ `string PyRepr(object obj)`
|
|
||||||
|
|
||||||
Convert a Python object to a string representation. It is equivalent to `repr(obj)` in Python.
|
|
||||||
|
|
||||||
+ `int PyHash(object obj)`
|
|
||||||
|
|
||||||
Get the hash value of a Python object. It is equivalent to `hash(obj)` in Python.
|
|
||||||
|
|
||||||
+ `List<object> PyList(object obj)`
|
|
||||||
|
|
||||||
Convert an `Iterable` Python object to a list. It is equivalent to `list(obj)` in Python.
|
|
||||||
|
|
||||||
### Callbacks
|
|
||||||
|
|
||||||
+ `System.Action<string> stdout = Debug.Log`
|
|
||||||
|
|
||||||
A callback that will be called when the Python code invokes `print` function.
|
|
||||||
By default, it will print the message to Unity console.
|
|
||||||
|
|
||||||
+ `System.Action<string> stderr = null`
|
|
||||||
|
|
||||||
A callback that will be called when the Python code emits an error message.
|
|
||||||
By default, an Exception will be raised.
|
|
||||||
You can set it to `Debug.LogError` for printing to the Unity Console.
|
|
||||||
|
|
||||||
### Debug Flag
|
|
||||||
|
|
||||||
+ `bool debug = false`
|
|
||||||
|
|
||||||
A flag that controls whether to print debug messages to Unity console.
|
|
||||||
You can set it to `true` to enable debug messages, or `false` to disable them.
|
|
@ -28,7 +28,8 @@ for line in lines:
|
|||||||
output.append('```cpp\n')
|
output.append('```cpp\n')
|
||||||
|
|
||||||
with open('docs/references.md', 'w', encoding='utf-8') as f:
|
with open('docs/references.md', 'w', encoding='utf-8') as f:
|
||||||
f.write('''---label: References
|
f.write('''---
|
||||||
|
label: References
|
||||||
icon: code
|
icon: code
|
||||||
order: 2
|
order: 2
|
||||||
---
|
---
|
||||||
|
Loading…
x
Reference in New Issue
Block a user