Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #51827 > unrolled thread
| Started by | "David M. Cotter" <me@davecotter.com> |
|---|---|
| First post | 2013-08-02 17:55 -0700 |
| Last post | 2013-08-05 15:55 -0700 |
| Articles | 3 — 2 participants |
Back to article view | Back to comp.lang.python
PyArg_ParseTuple() when the type could be anything? "David M. Cotter" <me@davecotter.com> - 2013-08-02 17:55 -0700
Re: PyArg_ParseTuple() when the type could be anything? Stefan Behnel <stefan_ml@behnel.de> - 2013-08-03 16:31 +0200
Re: PyArg_ParseTuple() when the type could be anything? "David M. Cotter" <me@davecotter.com> - 2013-08-05 15:55 -0700
| From | "David M. Cotter" <me@davecotter.com> |
|---|---|
| Date | 2013-08-02 17:55 -0700 |
| Subject | PyArg_ParseTuple() when the type could be anything? |
| Message-ID | <d89fba21-68b0-47b4-818b-2c8e80b35ff8@googlegroups.com> |
I'd like to be able to use PyArg_ParseTuple() in a generic way.
for example, i'd like to have all commands start with 1 integer parameter, and this "commandID" will inform me of what parameters come next (via LUT).
knowing that i can then call ParseTuple again with the proper parameters.
like this:
if (PyArg_ParseTuple(args, "i|", &commandID)) {
switch (commandID) {
case cmd_with_str: {
const char *strZ = NULL;
if (PyArg_ParseTuple(args, "is", &commandID, &strZ)) {
// do something with string
}
break;
}
case cmd_with_float: {
float valF = -1;
if (PyArg_ParseTuple(args, "if", &commandID, &valF)) {
// do something with float
}
break;
}
}
}
is there a way to achieve this? the "i|" at the start is not working
[toc] | [next] | [standalone]
| From | Stefan Behnel <stefan_ml@behnel.de> |
|---|---|
| Date | 2013-08-03 16:31 +0200 |
| Message-ID | <mailman.156.1375540313.1251.python-list@python.org> |
| In reply to | #51827 |
David M. Cotter, 03.08.2013 02:55:
> I'd like to be able to use PyArg_ParseTuple() in a generic way.
>
> for example, i'd like to have all commands start with 1 integer parameter, and this "commandID" will inform me of what parameters come next (via LUT).
>
> knowing that i can then call ParseTuple again with the proper parameters.
>
> like this:
>
> if (PyArg_ParseTuple(args, "i|", &commandID)) {
>
> switch (commandID) {
>
> case cmd_with_str: {
> const char *strZ = NULL;
>
> if (PyArg_ParseTuple(args, "is", &commandID, &strZ)) {
> // do something with string
> }
> break;
> }
>
> case cmd_with_float: {
> float valF = -1;
>
> if (PyArg_ParseTuple(args, "if", &commandID, &valF)) {
> // do something with float
> }
> break;
> }
> }
> }
>
> is there a way to achieve this? the "i|" at the start is not working
If you're willing to switch to Cython, here's an (untested) example:
cdef enum:
cmd_with_str = 1
cmd_with_float = 2
cdef int command_id = args[0]
if command_id == cmd_with_str:
str_z = args[1] # it's an object, so use it as such
print(str_z)
elif command_id == cmd_with_float:
val_f = <float>args[1] # converting to C float here
...
else:
raise ValueError("unknown command")
Two comments:
1) you can obviously do the same in C, by writing a bit more code. It would
likely be a lot slower, though, and you'd have to take care of error
handling etc.
2) you might want to rethink your design as this is a rather unpythonic
API. Although it depends on who (or what) you are expecting to use it.
Stefan
[toc] | [prev] | [next] | [standalone]
| From | "David M. Cotter" <me@davecotter.com> |
|---|---|
| Date | 2013-08-05 15:55 -0700 |
| Message-ID | <7756ab34-3545-4dba-8a7e-c94d469681ce@googlegroups.com> |
| In reply to | #51827 |
i was able to get what i wanted by simply iterating over the tupile instead of using ParseTupile, then just query the type, then convert the type to C and move on to the next. totally great, now i can pass N different argument types to a single function, and have the C side deal gracefully with whatever types are sent.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web