473,324 Members | 2,531 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,324 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 1607
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;
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.