mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-22 12:30:19 +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')
|
||||
|
||||
with open('docs/references.md', 'w', encoding='utf-8') as f:
|
||||
f.write('''---label: References
|
||||
f.write('''---
|
||||
label: References
|
||||
icon: code
|
||||
order: 2
|
||||
---
|
||||
|
Loading…
x
Reference in New Issue
Block a user