Re: Using my routines as functions AND methods
On 1/3/2024 8:00 PM, Alan Gauld via Python-list wrote: On 03/01/2024 22:47, Guenther Sohler via Python-list wrote: Hi, In my cpython i have written quite some functions to modify "objects". and their python syntax is e.g.\ translate(obj, vec). e.g whereas obj is ALWAYS first argument. However, I also want to use these functions as class methods without having to write the function , twice. When using the SAME function as a methos, the args tuple must insert/contain "self" in the first location, so i have written a function to do that: I'm probably missing something obvious here but can't you just assign your function to a class member? def myFunction(obj, ...): ... class MyClass: myMethod = myFunction Then you can call it as myObject = MyClass() myObject.myMethod() A naive example seems to work but I haven't tried anything complex so there is probably a catch. But sometimes the simple things just work? That works if you assign the function to a class instance, but not if you assign it to a class. def f1(x): print(x) f1('The plain function') class Class1: pass class Class2: pass c1 = Class1() c1.newfunc = f1 c1.newfunc('f1 assigned to instance') # Works as intended Class2.newfunc = f1 c2 = Class2() c2.newfunc('f1 assigned to class') # Complains about extra argument -- https://mail.python.org/mailman/listinfo/python-list
Re: Using my routines as functions AND methods
On 04/01/2024 04:17, Thomas Passin via Python-list wrote: >> I'm probably missing something obvious here but can't you >> just assign your function to a class member? >> >> def myFunction(obj, ...): ... >> >> class MyClass: >> myMethod = myFunction > > That works if you assign the function to a class instance, but not if > you assign it to a class. > > def f1(x): > print(x) > f1('The plain function') > > class Class1: > pass > > class Class2: > pass > > c1 = Class1() > c1.newfunc = f1 > c1.newfunc('f1 assigned to instance') # Works as intended > > Class2.newfunc = f1 > c2 = Class2() > c2.newfunc('f1 assigned to class') # Complains about extra argument Yes but I did the assignment inside the class definition and that seemed to work just fine: >>> def g(obj, st): print(st, obj.v) ... >>> class D: ...def __init__(self,v): self.v = v ...m = g ... >>> d = D(66) >>> g(d,'val = ') val = 66 >>> d.m('v = ') v = 66 -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos -- https://mail.python.org/mailman/listinfo/python-list
Re: Using my routines as functions AND methods
Hi list The approach with defining the methods from python appears to be a very good idea and it also works for classes, defined in python side. However, when I try this one: def mytrans(self): print(self) c=cube() cls=c.__class__ cls.trans=mytrans I get this: Traceback (most recent call last): File "", line 8, in TypeError: cannot set 'trans' attribute of immutable type 'PyOpenSCAD' The Problem is probably that PyOpenSCAD is a class not defined on python side but on c++ side, I fear that I need to solution in c++ side. ... On Wed, Jan 3, 2024 at 11:47 PM Guenther Sohler wrote: > Hi, > > In my cpython i have written quite some functions to modify "objects". > and their python syntax is e.g.\ > > translate(obj, vec). e.g whereas obj is ALWAYS first argument. > > on c side this functions looks like: > PyObject *python_translate(PyObject *self, PyObject *args, PyObject > *kwargs) > > this works great when specifying a list of functions in PyModuleDef > structure. > > However, I also want to use these functions as class methods without > having to > write the function , twice. When using the SAME function as a methos, the > args tuple must insert/contain "self" in the first location, so i have > written a function to do that: > > PyObject *python_oo_args(PyObject *self, PyObject *args) // returns new > reference, > { > int i; > PyObject *item; > int n = PyTuple_Size(args); > PyObject *new_args = PyTuple_New(n + 1); > PyTuple_SetItem(new_args, 0, self); > > for (i = 0; i < PyTuple_Size(args); i++) { > item = PyTuple_GetItem(args, i); > PyTuple_SetItem(new_args, i + 1, item); > } > return new_args; > } > > To fill in method array, i have created a #define like this: > > #define OO_METHOD_ENTRY(name,desc) \ > { #name, (PyCFunction) ( [ ] (PyObject *self, PyObject *args) -> > PyObject * { \ > PyObject *new_args = python_oo_args(self, args); \ > PyObject *result = python_##name(self, new_args, NULL); \ > return result; } ), METH_VARARGS | METH_KEYWORDS, (desc)}, > > (this uses a lambda function) > > and use this in the array as: > > PyMethodDef PyOpenSCADMethods[] = { > OO_METHOD_ENTRY(translate,"Move Object") > OO_METHOD_ENTRY(right,"Right Object") > > Using this i can reuse all the functions as methods, > but its not 100% stable/bulletproof and crashes sometimes. > So there is the bug ? > Is there a better approach to reach my goal ? > > > thank you > > -- https://mail.python.org/mailman/listinfo/python-list