|
| 1 | +package py3 |
| 2 | + |
| 3 | +import ( |
| 4 | + "reflect" |
| 5 | +) |
| 6 | + |
| 7 | +func GoToPyObject(o interface{}) *PyObject { |
| 8 | + to := reflect.TypeOf(o) |
| 9 | + valOf := reflect.ValueOf(o) |
| 10 | + |
| 11 | + if o == nil { |
| 12 | + return Py_RETURN_NONE().AsObj() |
| 13 | + } |
| 14 | + //*PyObject return |
| 15 | + if to.AssignableTo(reflect.TypeOf(&PyObject{})) { |
| 16 | + return o.(*PyObject) |
| 17 | + } |
| 18 | + if valOf.CanInt() { |
| 19 | + return PyLongFromLongLong(valOf.Int()).AsObj() |
| 20 | + } |
| 21 | + if valOf.CanUint() { |
| 22 | + return PyLongFromLongLong(int64(valOf.Uint())).AsObj() |
| 23 | + } |
| 24 | + if valOf.CanFloat() { |
| 25 | + return PyLong_FromDouble(valOf.Float()).AsObj() |
| 26 | + } |
| 27 | + |
| 28 | + if to.Kind() == reflect.Bool { |
| 29 | + return NewPyBool(valOf.Bool()) |
| 30 | + } |
| 31 | + if to.Kind() == reflect.String { |
| 32 | + return NewPyUnicode(valOf.String()).AsObj() |
| 33 | + } |
| 34 | + |
| 35 | + if to.Kind() == reflect.Slice { |
| 36 | + l := NewPyList(0) |
| 37 | + size := valOf.Len() |
| 38 | + for i := 0; i < size; i++ { |
| 39 | + item := valOf.Index(i).Interface() |
| 40 | + o := GoToPyObject(item) |
| 41 | + defer o.DecRef() |
| 42 | + l.Append(o) |
| 43 | + } |
| 44 | + return l.AsObj() |
| 45 | + } |
| 46 | + if to.Kind() == reflect.Map { |
| 47 | + d := NewPyDict() |
| 48 | + keys := valOf.MapKeys() |
| 49 | + for _, key := range keys { |
| 50 | + k := GoToPyObject(key.Interface()) |
| 51 | + defer k.DecRef() |
| 52 | + v := GoToPyObject(valOf.MapIndex(key).Interface()) |
| 53 | + defer v.DecRef() |
| 54 | + d.SetItem(k, v) |
| 55 | + } |
| 56 | + return d.AsObj() |
| 57 | + } |
| 58 | + return Py_RETURN_NONE().AsObj() |
| 59 | +} |
| 60 | + |
| 61 | +func PyObjectToGo(o *PyObject, to reflect.Type) any { |
| 62 | + //*PyObject return |
| 63 | + if to.AssignableTo(reflect.TypeOf(o)) { |
| 64 | + return o |
| 65 | + } |
| 66 | + if to.Kind() == reflect.Int { |
| 67 | + return int(o.AsLongLong()) |
| 68 | + } |
| 69 | + if to.Kind() == reflect.Int8 { |
| 70 | + return int8(o.AsLongLong()) |
| 71 | + } |
| 72 | + if to.Kind() == reflect.Int16 { |
| 73 | + return int16(o.AsLongLong()) |
| 74 | + } |
| 75 | + if to.Kind() == reflect.Int32 { |
| 76 | + return int32(o.AsLongLong()) |
| 77 | + } |
| 78 | + if to.Kind() == reflect.Int64 { |
| 79 | + return int64(o.AsLongLong()) |
| 80 | + } |
| 81 | + |
| 82 | + if to.Kind() == reflect.Uint { |
| 83 | + return uint(o.AsLongLong()) |
| 84 | + } |
| 85 | + if to.Kind() == reflect.Uint8 { |
| 86 | + return uint8(o.AsLongLong()) |
| 87 | + } |
| 88 | + if to.Kind() == reflect.Uint16 { |
| 89 | + return uint16(o.AsLongLong()) |
| 90 | + } |
| 91 | + if to.Kind() == reflect.Uint32 { |
| 92 | + return uint32(o.AsLongLong()) |
| 93 | + } |
| 94 | + if to.Kind() == reflect.Uint64 { |
| 95 | + return uint64(o.AsLongLong()) |
| 96 | + } |
| 97 | + |
| 98 | + if to.Kind() == reflect.Uintptr { |
| 99 | + return uintptr(o.AsLongLong()) |
| 100 | + } |
| 101 | + |
| 102 | + if to.Kind() == reflect.Bool { |
| 103 | + return o.AsInt() != 0 |
| 104 | + } |
| 105 | + if to.Kind() == reflect.String { |
| 106 | + return o.AsUTF8() |
| 107 | + } |
| 108 | + if to.Kind() == reflect.Float32 { |
| 109 | + return float32(o.AsDouble()) |
| 110 | + } |
| 111 | + if to.Kind() == reflect.Float64 { |
| 112 | + return float64(o.AsDouble()) |
| 113 | + } |
| 114 | + if to.Kind() == reflect.Slice { |
| 115 | + l := reflect.New(to).Elem() |
| 116 | + pyL := PyListFromObj(o.AsObj()) |
| 117 | + for i := int64(0); i < pyL.Size(); i++ { |
| 118 | + l = reflect.Append(l, reflect.ValueOf(PyObjectToGo(pyL.GetItem(i), to.Elem()))) |
| 119 | + } |
| 120 | + return l.Interface() |
| 121 | + } |
| 122 | + if to.Kind() == reflect.Map { |
| 123 | + l := reflect.MakeMap(to) |
| 124 | + pyD := PyDictFromObj(o.AsObj()) |
| 125 | + keys := PyListFromObj(pyD.Keys()) |
| 126 | + defer keys.DecRef() |
| 127 | + for i := int64(0); i < keys.Size(); i++ { |
| 128 | + k := keys.GetItem(i) |
| 129 | + goK := PyObjectToGo(k, to.Key()) |
| 130 | + l.SetMapIndex(reflect.ValueOf(goK), reflect.ValueOf(PyObjectToGo(pyD.GetItem(k), to.Elem()))) |
| 131 | + } |
| 132 | + return l.Interface() |
| 133 | + } |
| 134 | + if to.Kind() == reflect.Func { |
| 135 | + f := reflect.MakeFunc(to, func(args []reflect.Value) (results []reflect.Value) { |
| 136 | + pyArgs := NewPyTuple(int64(len(args))) |
| 137 | + for i, arg := range args { |
| 138 | + pyArgs.SetItem(int64(i), GoToPyObject(arg.Interface())) |
| 139 | + } |
| 140 | + rets := o.Call(pyArgs.AsObj(), PyNil) |
| 141 | + //如果声明函数不需要返回 |
| 142 | + if to.NumOut() == 0 { |
| 143 | + return nil |
| 144 | + } |
| 145 | + tp := rets.Type() |
| 146 | + defer tp.DecRef() |
| 147 | + |
| 148 | + goRets := make([]reflect.Value, 0) |
| 149 | + |
| 150 | + //如果是单个返回 |
| 151 | + if tp.Name() != "tuple" { |
| 152 | + if to.NumOut() != 1 { |
| 153 | + k := make([]reflect.Value, 0) |
| 154 | + for i := 0; i < to.NumOut(); i++ { |
| 155 | + k = append(k, reflect.ValueOf(reflect.New(to.Out(i)).Elem().Interface())) |
| 156 | + } |
| 157 | + PyErr_SetString(PyExc_ValueError(), "返回参数不正确") |
| 158 | + return k |
| 159 | + } |
| 160 | + goRets = append(goRets, reflect.ValueOf(PyObjectToGo(rets, to.Out(0)))) |
| 161 | + } else { |
| 162 | + tpRets := PyTupleFromObj(rets.AsObj()) |
| 163 | + if int64(to.NumOut()) != tpRets.Size() { |
| 164 | + k := make([]reflect.Value, 0) |
| 165 | + for i := 0; i < to.NumOut(); i++ { |
| 166 | + k = append(k, reflect.ValueOf(reflect.New(to.Out(i)).Elem().Interface())) |
| 167 | + } |
| 168 | + PyErr_SetString(PyExc_Exception(), "返回参数不正确") |
| 169 | + return k |
| 170 | + } |
| 171 | + for i := int64(0); i < tpRets.Size(); i++ { |
| 172 | + goRets = append(goRets, reflect.ValueOf(PyObjectToGo(tpRets.GetItem(i), to.Out(0)))) |
| 173 | + } |
| 174 | + } |
| 175 | + return goRets |
| 176 | + }) |
| 177 | + return f.Interface() |
| 178 | + } |
| 179 | + |
| 180 | + return o |
| 181 | +} |
0 commit comments