Skip to content

LLGo Bindings design for Python class #47

Description

@toaction

Class

Convert classes to structs, implementing inheritance-like relationships through embedding (supports multiple inheritance)

type Animal struct {
    py.Object
}

type Dog struct {
    Animal
}

Instance

Use package-level constructor functions to create instances:

//go:linkname NewDog py.Dog
func NewDog(name *py.Object) *py.Object

Considering XGo supports static methods:

type Dog struct {}

func Dog.new(name *py.Object) *py.Object

It can also be converted to the corresponding Go function:

//go:linkname Gops_Dog_new py.Dog
func Gops_Dog_new(name *py.Object) *py.Object

Methods

Methods in Python classes include instance methods, magic methods, static methods, and class methods.

For instance methods and magic methods, the symbol linking approach is:

# Instance method
mod.Dog.speak(dog)
# Magic method
mod.Dog.__str__(dog)

The first parameter of the method must be an instance object, so they are converted to struct methods:

For magic methods, remove the leading and trailing underscores to make them more compliant with naming conventions and user habits.

//llgo:link (*Dog).Speak py.Dog.speak
func (d *Dog) Speak() *py.Object {
    return nil
}
//llgo:link (*Dog).Str py.Dog.__str__
func (d *Dog) Str() *py.Object {
    return nil
}

Class methods and static methods are called independently of class instances, with symbol linking approach:

# class method
mod.Dog.bark("Hello")
# static method
mod.Dog.sleep()

Considering XGo supports static methods, they are converted to functions that comply with XGo specifications:

//go:linkname Gops_Dog_bark py.Dog.bark
func Gops_Dog_bark(msg *py.Object) *py.Object

//go:linkname Gops_Dog_sleep py.Dog.sleep
func Gops_Dog_sleep() *py.Object

Property

Python recommends using property to implement attribute encapsulation and access control.

class Dog(Animal):
    @property
    def age(self):
        return self._age
    @age.setter
    def age(self, age):
        self._age = age

Symbol linking approach:

# get
age = mod.Dog.age.__get__(dog)
# set
mod.Dog.age.__set__(dog, 4)

Attributes are accessed and set through method calls, with the first parameter being the instance object. Therefore, they are converted to struct methods.

For property getter operations, the Get prefix is not added to align with user habits.

//llgo:link (*Dog).Age py.Dog.age.__get__
func (d *Dog) Age() *py.Object {
    return nil
}

//llgo:link (*Dog).SetAge py.Dog.age.__set__
func (d *Dog) SetAge(age *py.Object) {
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions