Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #88035
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Subject | Re: Supply condition in function call |
| Date | 2015-03-26 10:03 +0100 |
| Organization | None |
| References | <87r3sc9stg.fsf@uriel.graune.org> <20150326070600.GA2199@cskk.homeip.net> |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.190.1427360650.10327.python-list@python.org> (permalink) |
Cameron Simpson wrote:
> On 26Mar2015 07:27, Manuel Graune <manuel.graune@koeln.de> wrote:
>>Gary Herron <gherron@digipen.edu> writes:
>>> On 03/25/2015 10:29 AM, Manuel Graune wrote:
>>>> def test1(a, b, condition="True"):
>>>> for i,j in zip(a,b):
>>>> c=i+j
>>>> if eval(condition):
>>>> print("Foo")
>>>>
>>>> test1([0,1,2,3],[1,2,3,4],"i+j >4")
>>>> print("Bar")
>>>> test1([0,1,2,3],[1,2,3,4],"c >4")
>>>> print("Bar")
>>>> test1([0,1,2,3],[1,2,3,4],"a[i] >2")
>>>
>>> This is nicely done with lambda expressions:
>>>
>>> To pass in a condition as a function:
>>> test1([0,1,2,3],[1,2,3,4], lambda i,j: i+j<4)
>>>
>>> To check the condition in the function:
>>> if condition(i,j):
>>
>>This seems to be the right direction and a good solution for simple
>>cases. Unfortunately this:
>>
>>> To get the full range of conditions, you will need to include all the
>>> variables needed by any condition you can imagine. So the above
>>> suggestions may need to be expanded to:
>>> ... lambda i,j,a,b: ... or whatever
>>>
>>> and
>>> ... condition(i,j,a,b) ... or whatever
>>>
>>
>>is not as concise as I had hoped for. Is there a possibility to do
>>(maybe with a helper function inside the main function's body) solve
>>this more elegantly? I'm thinking of some combination of e. g. **kwargs,
>>dir() and introspection.
>
> Yes.
>
> Consider locals():
>
> https://docs.python.org/3/library/functions.html#locals
>
> which is a built in function returning a copy of the current local
> variables in a dict. Example:
>
> condition_test = lambda vars: vars['i'] + vars[j'] > 4
>
> def test1(a, b, condition):
> for i, j in zip(a,b):
> c = i + j
> if condition(locals()):
> print("Foo")
>
> test1([0,1,2,3], [1,2,3,4], condition_test)
>
> This passes the local variables inside test1() to "condition" as a single
> parameter. Now, I grant that vars['i'] is a miracle of tediousness. So
> consider this elaboration:
>
> from collections import namedtuple
>
> condition_test = lambda vars: vars.i + vars.j > 4
>
> def test1(a, b, condition):
> for i, j in zip(a,b):
> c = i + j
> vars = locals()
> varnames = list(vars.keys())
That leaves varnames in undefined order. Consider
varnames = sorted(vars)
instead or pass the list of arguments explicitly, optionally with some
inspect fallback:
$ cat pass_condition_inspect.py
import inspect
def test3(a, b, condition, args=None):
if args is None:
args = inspect.getargspec(condition).args
for i, j in zip(a,b):
c = i + j
_locals = locals()
if condition(*[_locals[name] for name in args]):
print("Foo", i, j)
def condition(c, i):
return i * i > c
test3([1, 2, 3], [2, 3, 4], condition)
print("---")
# note reverse order of argument names
test3([1, 2, 3], [2, 3, 4], condition, ["i", "c"])
$ python3 pass_condition_inspect.py
Foo 3 4
---
Foo 1 2
Foo 2 3
Foo 3 4
A simpler alternative is changing the signature of condition() and passing
keyword arguments:
$ cat pass_condition.py
def test2(a, b, condition):
for i, j in zip(a,b):
c = i + j
if condition(**locals()):
print("Foo", i, j)
def condition(c, i, **unused):
return i * i > c
test2([1, 2, 3], [2, 3, 4], condition)
$ python3 pass_condition.py
Foo 3 4
Creating a locals() dict on every iteration is still costly, and personally
I would prefer the tighter interface where you pass a limited set of
arguments explicitly.
> varstupletype = namedtuple("locals", varnames)
> varstuple = varstupletype(*[ vars[k] for k in varnames ])
> if condition(varstuple):
> print("Foo")
>
> Here, the condition_test function/lambda uses "vars.i" and "vars.j", which
> i think you'll agree is easier to read and write. The price is the
> construction of a "namedtuple" to hold the variable name values. See:
>
>
https://docs.python.org/3/library/collections.html#collections.namedtuple
>
> So the (untested) code above:
>
> - get the locals() as before
> - get the names of the variables; it is important to have this in a
> array because we need to access the values in the same order when we
> make the tuple - make a new namedtuple class "varstupletype", which is
> used to make the named tuple - make the named tuple itself with the
> values of the variables in order
>
> If you're writing a lot of test functions like test1 you can push the
> namedtuple stuff off into a helper function:
>
> def vartuple(vars):
> varnames = list(vars.keys())
> varstupletype = namedtuple("locals", varnames)
> varstuple = varstupletype(*[ vars[k] for k in varnames ])
> return varstuple
>
> and then "test1()" can look like this:
>
> def test1(a, b, condition):
> for i, j in zip(a,b):
> c = i + j
> if condition(vartuple(locals())):
> print("Foo")
>
> which makes it much easier to write test2 and so on later.
Back to comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-25 18:29 +0100
Re: Supply condition in function call Joel Goldstick <joel.goldstick@gmail.com> - 2015-03-25 13:41 -0400
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-25 18:51 +0100
Re: Supply condition in function call Joel Goldstick <joel.goldstick@gmail.com> - 2015-03-25 14:17 -0400
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-25 12:22 -0600
Re: Supply condition in function call Joel Goldstick <joel.goldstick@gmail.com> - 2015-03-25 14:42 -0400
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-25 11:44 -0600
Re: Supply condition in function call Grant Edwards <invalid@invalid.invalid> - 2015-03-25 19:53 +0000
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-25 14:49 -0600
Re: Supply condition in function call Grant Edwards <invalid@invalid.invalid> - 2015-03-26 15:41 +0000
Re: Supply condition in function call Terry Reedy <tjreedy@udel.edu> - 2015-03-25 14:50 -0400
Re: Supply condition in function call Gary Herron <gherron@digipen.edu> - 2015-03-25 12:13 -0700
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-25 21:02 -0700
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-26 17:00 +1100
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-26 18:41 -0700
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-27 12:56 +1100
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-26 19:21 -0700
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-27 15:34 +1100
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-27 06:48 -0700
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-28 01:17 +1100
Re: Supply condition in function call Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-03-27 16:00 +0000
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-28 18:32 +1100
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-28 18:45 +1100
Re: Supply condition in function call Larry Hudson <orgnut@yahoo.com> - 2015-03-27 17:26 -0700
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-27 18:27 -0700
Re: Supply condition in function call Marko Rauhamaa <marko@pacujo.net> - 2015-03-28 09:50 +0200
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-28 20:17 +1100
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-28 03:19 -0600
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-28 20:57 +1100
Re: Supply condition in function call Cameron Simpson <cs@zip.com.au> - 2015-03-30 09:35 +1100
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-30 00:46 +0200
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-26 20:25 -0600
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-26 19:46 -0700
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-26 07:27 +0100
Re: Supply condition in function call Cameron Simpson <cs@zip.com.au> - 2015-03-26 18:06 +1100
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-27 21:02 +0100
Re: Supply condition in function call Cameron Simpson <cs@zip.com.au> - 2015-03-28 09:55 +1100
Re: Supply condition in function call Peter Otten <__peter__@web.de> - 2015-03-26 10:03 +0100
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-27 20:46 +0100
Re: Supply condition in function call Peter Otten <__peter__@web.de> - 2015-03-27 21:38 +0100
Re: Supply condition in function call smap <askme.first@thankyouverymuch.invalid> - 2015-03-28 08:58 +0000
csiph-web