Re: Python 3.12.1, Windows 11: shebang line #!/usr/bin/env python3 doesn't work any more
> On 2 Jan 2024, at 17:24, Thomas Passin via Python-list > wrote: > > You might learn about this if you happen to read and remember the right part > of the Python docs. Otherwise you have no idea what py.exe is up to nor how > it does it. I would say that most people don't know there's an ini file, let > alone what it can do. Of course this situation isn't unique to py.exe! On discuss.python.org we will share the link to the python windows docs and often to this specific section: https://docs.python.org/3/using/windows.html#python-launcher-for-windows To create a py.ini does require a user to understand what %localappdata% means. Some windows users, reasonable, do not use the CLI and know about that syntax for environment variables. Barry -- https://mail.python.org/mailman/listinfo/python-list
Using my routines as functions AND methods
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
Re: Using my routines as functions AND methods
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? -- 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
On 1/3/2024 11:17 PM, Thomas Passin wrote:
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
If your requirements are not very tricky, you can write a
convert-to-method function yourself:
def f1(x):
print(x)
f1('The plain function')
class Class2:
pass
def convert_method(f):
"""Assign existing method without a "self" arg
as a class's method.
"""
def fnew(instance, *args):
f(*args)
return fnew
Class2.newfunc = convert_method(f1)
c2 = Class2()
c2.newfunc('f1 assigned as method of Class2') # Prints the arg
This example does not make f1 aware of the self argument, but you asked
to convert an existing function, and that function would not be aware of
the self parameter. It's much like a decorator function, but is not here
being used as a decorator. If you meant something else, please think out
what you want and explain that.
--
https://mail.python.org/mailman/listinfo/python-list
Re: Using my routines as functions AND methods
Thank you for your answers.
apparently I did not express myself clear enough. Let me rephrase.
I got an embedded C function like this:
==
PyObject *python_translate(PyObject *self, PyObject *args, PyObject *kwargs)
{
char *kwlist[] = {"obj", "v", NULL};
PyObject *v = NULL;
PyObject *obj = NULL;
double x = 0, y = 0, z = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO", kwlist,
&obj,
&v
)) {
PyErr_SetString(PyExc_TypeError, "Error during parsing
translate(object,vec3)");
return NULL;
}
...
PyMethodDef PyOpenSCADFunctions[] = {
{"translate", (PyCFunction) python_translate, METH_VARARGS |
METH_KEYWORDS, "Move Object."},
...
static PyModuleDef OpenSCADModule = {
PyModuleDef_HEAD_INIT,
"openscad",
"OpenSCAD Python Module",
-1,
PyOpenSCADFunctions,
...
};
From within python i can successfully use it with
translate(my_object, [2,0,0])
my_object is an instance of embedded class PyOpenSCADType, so alternatively
I want to use my function as method too, like so:
my_object.translate([2,0,0])
WITHOUT duplicating the code for python_translate
So the idea is to call the translate-function from within the translate
method and insert "self" into the args tuple.
However my solution somewhat works but is not very stable and quite prone
to crash.
Which are my alertnatives ?
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
