473,224 Members | 1,334 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,224 software developers and data experts.

Returning actual argument expression to a function call?

Hi,
# If I have a function definition
def f1(arg):
global capturecall
if capturecall:
...
do_normal_stuff(arg)

# and its later use:
def f2():
...
return f1(a and (b or c))

# I would like to do:
capturecall = False
result = f2()
# And get the equivalent of do_normal_stuff(a and(b or c))

# But also to do:
capturecall = True
result = f2()
# And get the same result, but also save the actual
# calling arguments to f1 either as a string:
# "a and (b or c))"
# Or a code object computing a and(b or c)
# I caould change f1 to expect a function instead and do:
def f1b(arg):
global capturecall
if capturecall:
save(arg)
return do_normal_stuff(arg())

# And then use it like this:
def f2b():
...
return f1b(lambda : (a and (b or c)) )

# The problem is that for my application to work,
# Python newbies would have to write lambda when they
# know they are after the result. Its my program
# that would require the lambda (or def), which
# is a distraction from their problem.

Any ideas on implementing f1 so I can do f2?

Thanks in advance, Paddy.
P.S. You might also have multiple calls where I
would need to capture each individual argument
expression of f1 e.g:
def f3():
...
return f1(a and b) or e or f1(c and d)

Nov 10 '07 #1
6 1604
On Fri, 09 Nov 2007 22:03:00 -0800, Paddy wrote:
Hi,
# If I have a function definition
....
# The problem is that for my application to work,
# Python newbies would have to write lambda when they
# know they are after the result.
I don't understand why you think this is the case.

Its my program
# that would require the lambda (or def), which
# is a distraction from their problem.
....
Any ideas on implementing f1 so I can do f2?
I've read your post three times now, and I'm still not absolutely sure
what you're trying to accomplish.

I think you want something like this:

You have a function f1(*args) which returns a result. You want a global
flag that tells f1 to stick it's arguments in a global variable. Am I
close?

If so, something like this should work:

# Define someplace to store the arguments.
last_args = (None, None)
# And a flag.
capturecall = True

# A decorator to wrap a function.
def capture_args(func):
def f(*args, **kwargs):
if capturecall:
global last_args
last_args = (args, kwargs)
return func(*args, **kwargs)
f.__name__ = "capturing_" + func.__name__
return f

Now you can do this:
>>def f1(x, y=3):
.... return x + y
....
>>f1 = capture_args(f1)
f1(5)
8
>>last_args
((5,), {})
>>@capture_args
.... def f2(x):
.... return 2**x
....
>>f2(0.4+1)
2.6390158215457884
>>last_args
((1.3999999999999999,), {})

In the second example, if you are trying to capture the expression "0.4
+1", I don't think that is possible. As far as I know, there is no way
for the called function to find out how its arguments were created. I
think if you need that, you need to create your own parser.

--
Steven.
Nov 10 '07 #2
En Sat, 10 Nov 2007 03:03:00 -0300, Paddy <pa*******@googlemail.com>
escribió:
Hi,
# If I have a function definition
def f1(arg):
global capturecall
if capturecall:
...
do_normal_stuff(arg)

# and its later use:
def f2():
...
return f1(a and (b or c))

# But also to do:
capturecall = True
result = f2()
# And get the same result, but also save the actual
# calling arguments to f1 either as a string:
# "a and (b or c))"
# Or a code object computing a and(b or c)
Would be enough to have the source line text?

<code test1.py>
def extract_caller_info():
import sys, traceback
return traceback.extract_stack(sys._getframe(2), limit=1)

def f1(arg):
if capturecall:
print extract_caller_info()
# do_normal_stuff(arg)

def f2():
a,b,c = 1,0,3
return f1(a and (b or c))

capturecall = True
result = f2()
</code>

output is like this:
[('test1.py', 12, 'f2', 'return f1(a and (b or c))')]

source file name, line number, function name, source line text.
P.S. You might also have multiple calls where I
would need to capture each individual argument
expression of f1 e.g:
def f3():
...
return f1(a and b) or e or f1(c and d)
Tell your users that they'll have better results if those two calls are
split on different lines:

def f3():
return (f1(a and b)
or e
or f1(c and d))

Output:
[('test1.py', 18, 'f3', 'return (f1(a and b)')]
[('test1.py', 20, 'f3', 'or f1(c and d))')]

--
Gabriel Genellina

Nov 10 '07 #3
On Nov 10, 6:54 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.auwrote:
In the second example, if you are trying to capture the expression "0.4
+1", I don't think that is possible. As far as I know, there is no way
for the called function to find out how its arguments were created. I
think if you need that, you need to create your own parser.

--
Steven.
Unfortunately Steven, its exactly the expression that I want
rather than the expression result.

Thanks for your attempt, and I will try and make myself clearer
in the future (allthough I did take time over my initial post).

- Paddy.
Nov 10 '07 #4
On Nov 10, 7:02 am, "Gabriel Genellina" <gagsl-...@yahoo.com.ar>
wrote:
En Sat, 10 Nov 2007 03:03:00 -0300, Paddy <paddy3...@googlemail.com>
escribió:
Hi,
# If I have a function definition
def f1(arg):
global capturecall
if capturecall:
...
do_normal_stuff(arg)
# and its later use:
def f2():
...
return f1(a and (b or c))
# But also to do:
capturecall = True
result = f2()
# And get the same result, but also save the actual
# calling arguments to f1 either as a string:
# "a and (b or c))"
# Or a code object computing a and(b or c)

Would be enough to have the source line text?

<code test1.py>
def extract_caller_info():
import sys, traceback
return traceback.extract_stack(sys._getframe(2), limit=1)

def f1(arg):
if capturecall:
print extract_caller_info()
# do_normal_stuff(arg)

def f2():
a,b,c = 1,0,3
return f1(a and (b or c))

capturecall = True
result = f2()
</code>

output is like this:
[('test1.py', 12, 'f2', 'return f1(a and (b or c))')]

source file name, line number, function name, source line text.
P.S. You might also have multiple calls where I
would need to capture each individual argument
expression of f1 e.g:
def f3():
...
return f1(a and b) or e or f1(c and d)

Tell your users that they'll have better results if those two calls are
split on different lines:

def f3():
return (f1(a and b)
or e
or f1(c and d))

Output:
[('test1.py', 18, 'f3', 'return (f1(a and b)')]
[('test1.py', 20, 'f3', 'or f1(c and d))')]

--
Gabriel Genellina

Thanks Gabriel, that will alow me to move forward.

Nov 10 '07 #5
>>>>Paddy <pa*******@googlemail.com(P) wrote:
>PHi,
P# If I have a function definition
Pdef f1(arg):
P global capturecall
P if capturecall:
P ...
P do_normal_stuff(arg)
>P# and its later use:
Pdef f2():
P ...
P return f1(a and (b or c))
>P# I would like to do:
Pcapturecall = False
Presult = f2()
P# And get the equivalent of do_normal_stuff(a and(b or c))
>P# But also to do:
Pcapturecall = True
Presult = f2()
P# And get the same result, but also save the actual
P# calling arguments to f1 either as a string:
P# "a and (b or c))"
P# Or a code object computing a and(b or c)
>P# I caould change f1 to expect a function instead and do:
Pdef f1b(arg):
P global capturecall
P if capturecall:
P save(arg)
P return do_normal_stuff(arg())
>P# And then use it like this:
Pdef f2b():
P ...
P return f1b(lambda : (a and (b or c)) )
>P# The problem is that for my application to work,
P# Python newbies would have to write lambda when they
P# know they are after the result. Its my program
P# that would require the lambda (or def), which
P# is a distraction from their problem.
>PAny ideas on implementing f1 so I can do f2?
With Python this can't be done without either quoting the expression (make
a string out of it) or using a lambda. Lisp and C# can do this kind of thing.
--
Piet van Oostrum <pi**@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP 8DAE142BE17999C4]
Private email: pi**@vanoostrum.org
Nov 10 '07 #6
On Nov 10, 3:44 pm, Piet van Oostrum <p...@cs.uu.nlwrote:
With Python this can't be done without either quoting the expression (make
a string out of it) or using a lambda. Lisp and C# can do this kind of thing.
<WarpedHumour>
I'd like to propose we add '(<expr>) to Python. Pronounced tick-
brackets, it
surrounds an expression which is compiled into an anonymous function.

I have not thought this through apart from knowing that this is one
more
step towards Lisp heaven and submit no code as the implementation
will be trivial ;-)

Of course if my suggestion is not welcomed with open arms then this
is
Pythons last chance to escape terminal decline....
<WeftedHumour>
Nov 10 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: mjm | last post by:
Folks, Stroustrup indicates that returning by value can be faster than returning by reference but gives no details as to the size of the returned object up to which this holds. My question is...
17
by: Roland Hall | last post by:
Is there a way to return multiple values from a function without using an array? Would a dictionary object work better? -- Roland Hall /* This information is distributed in the hope that it...
7
by: BrianJones | last post by:
Hi, if you have a function, how is it possible to return an array? E.g.: unsigned long function(...) // what I want to do, obviously illegal I do know such would be possible by using a dynamic...
6
by: Jason Heyes | last post by:
I am interested in the lifetime of a function argument in two cases. They are: 1. void foo(Bar bar); 2. void foo(const Bar &bar); In each case I call foo like so: foo(Bar());
7
by: confusedcoder | last post by:
I found a strange piece of code that basically did the following: int doSomething(int& foo) { //manipulate the value of foo return foo; } int main(int argc, char* argv) {
11
by: vbgunz | last post by:
Hello all, I am just learning Python and have come across something I feel might be a bug. Please enlightenment me... The following code presents a challenge. How in the world do you provide an...
8
by: Michal Nazarewicz | last post by:
Hi, What does returning 0 from main() mean according to C89/C90 standard? I've found that in C99 it means successful termination (7.20.4.3p5) however as I'm editing book on C at Polish Wikibooks...
160
by: DiAvOl | last post by:
Hello everyone, Please take a look at the following code: #include <stdio.h> typedef struct person { char name; int age; } Person;
8
by: coolguyaroundyou | last post by:
See the below code: void func(int x) { printf("%d",x); } int main() { int j=0;
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.