Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #19721 > unrolled thread
| Started by | Olive <diolu@bigfoot.com> |
|---|---|
| First post | 2012-02-01 18:11 +0100 |
| Last post | 2012-02-01 18:50 +0100 |
| Articles | 18 — 9 participants |
Back to article view | Back to comp.lang.python
Question about name scope Olive <diolu@bigfoot.com> - 2012-02-01 18:11 +0100
Re: Question about name scope Rick Johnson <rantingrickjohnson@gmail.com> - 2012-02-01 09:21 -0800
Re: Question about name scope Ethan Furman <ethan@stoneleaf.us> - 2012-02-01 09:43 -0800
Re: Question about name scope Dave Angel <d@davea.name> - 2012-02-01 12:36 -0500
Re: Question about name scope Mel Wilson <mwilson@the-wire.com> - 2012-02-01 13:47 -0500
Re: Question about name scope Ian Kelly <ian.g.kelly@gmail.com> - 2012-02-01 14:49 -0700
Re: Question about name scope Ian Kelly <ian.g.kelly@gmail.com> - 2012-02-01 15:38 -0700
Re: Question about name scope Ethan Furman <ethan@stoneleaf.us> - 2012-02-01 14:24 -0800
Re: Question about name scope Ian Kelly <ian.g.kelly@gmail.com> - 2012-02-01 16:00 -0700
Re: Question about name scope Ethan Furman <ethan@stoneleaf.us> - 2012-02-01 15:08 -0800
Re: Question about name scope Ian Kelly <ian.g.kelly@gmail.com> - 2012-02-01 16:47 -0700
Re: Question about name scope Ethan Furman <ethan@stoneleaf.us> - 2012-02-01 14:53 -0800
Re: Question about name scope Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-02-02 00:34 +0000
Re: Question about name scope Ethan Furman <ethan@stoneleaf.us> - 2012-02-01 15:59 -0800
Re: Question about name scope Ethan Furman <ethan@stoneleaf.us> - 2012-02-01 15:41 -0800
Re: Question about name scope Ethan Furman <ethan@stoneleaf.us> - 2012-02-01 15:51 -0800
Re: Question about name scope Chris Rebert <clp2@rebertia.com> - 2012-02-01 09:38 -0800
Re: Question about name scope Christian Heimes <lists@cheimes.de> - 2012-02-01 18:50 +0100
| From | Olive <diolu@bigfoot.com> |
|---|---|
| Date | 2012-02-01 18:11 +0100 |
| Subject | Question about name scope |
| Message-ID | <20120201181117.5d35dddc@bigfoot.com> |
I am learning python and maybe this is obvious but I have not been able to see a solution. What I would like to do is to be able to execute a function within the namespace I would have obtained with from <module> import * For example if I write: def f(a): return sin(a)+cos(a) I could then do: from math import * f(5) But I have polluted my global namespace with all what's defined in math. I would like to be able to do something like "from math import *" at the f level alone. The main reason for this is the sympy module for CAS (computer algebra). It reimplement a lot of functions and define all the letters as symbolic variables. Writing sympy.<function> everywhere is inconvenient. Importing all the symbols in the global namespace would lead to name clash. It would be nice if I could import all the sympy names but for a given function only. Olive
[toc] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2012-02-01 09:21 -0800 |
| Message-ID | <2f7095cd-12ad-4031-9ebe-0c54ee3ad9c9@p13g2000yqd.googlegroups.com> |
| In reply to | #19721 |
On Feb 1, 11:11 am, Olive <di...@bigfoot.com> wrote: > But I have polluted my global namespace with all what's defined in > math. I would like to be able to do something like "from math import *" > at the f level alone. Seeing is believing! >>> dir() ['__builtins__', '__doc__', '__name__', '__package__'] >>> from math import * >>> dir() ['__builtins__', '__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc'] >>> ================================ RESTART ================================ >>> dir() ['__builtins__', '__doc__', '__name__', '__package__'] >>> from math import sin, cos >>> dir() ['__builtins__', '__doc__', '__name__', '__package__', 'cos', 'sin'] >>>
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-02-01 09:43 -0800 |
| Message-ID | <mailman.5310.1328117843.27778.python-list@python.org> |
| In reply to | #19721 |
Olive wrote:
> I am learning python and maybe this is obvious but I have not been able
> to see a solution. What I would like to do is to be able to execute a
> function within the namespace I would have obtained with from <module>
> import *
>
> For example if I write:
>
> def f(a):
> return sin(a)+cos(a)
>
> I could then do:
>
> from math import *
>
> f(5)
>
> But I have polluted my global namespace with all what's defined in
> math. I would like to be able to do something like "from math import *"
> at the f level alone.
If you are using Python 2.x you can do:
def f(a):
from sympy import *
return a(a) + d(a)
Python 3 does not allow * imports in functions, however, so you would
need to do:
def f(a):
from sympy import a,b,c,d,e,f,g,h,i,j,k,l,m
from sympy import n,o,p,q,r,s,t,u,v,w,x,y,z
return z(a) / f(a) + o(a)
Obviously, only import the functions you are actually going to use. ;)
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <d@davea.name> |
|---|---|
| Date | 2012-02-01 12:36 -0500 |
| Message-ID | <mailman.5311.1328117874.27778.python-list@python.org> |
| In reply to | #19721 |
On 02/01/2012 12:11 PM, Olive wrote:
> I am learning python and maybe this is obvious but I have not been able
> to see a solution. What I would like to do is to be able to execute a
> function within the namespace I would have obtained with from<module>
> import *
>
> For example if I write:
>
> def f(a):
> return sin(a)+cos(a)
>
> I could then do:
>
> from math import *
>
> f(5)
>
> But I have polluted my global namespace with all what's defined in
> math. I would like to be able to do something like "from math import *"
> at the f level alone.
>
> The main reason for this is the sympy module for CAS (computer algebra).
> It reimplement a lot of functions and define all the letters as symbolic
> variables. Writing sympy.<function> everywhere is inconvenient.
> Importing all the symbols in the global namespace would lead to name
> clash. It would be nice if I could import all the sympy names but for a
> given function only.
>
> Olive
>
>
Start by specifying python version and operating system.
I tried your experiment using Python 2.7 and Linux 11.04
def f(a):
from math import sin, cos
return sin(a) + cos(a)
print f(45)
Does what you needed, and neatly. The only name added to the global
namspace is f, of type function.
I was a bit surprised that using from math import * inside the
function worked, but it generates a warning:
olive.py:2: SyntaxWarning: import * only allowed at module level
def f(a):
I normally avoid any use of the "from XX import *" form, as it pollutes
the global name space. The only exception is when a library writer
documents that this is the "normal" way to interface to it. In this
case, he usually defines just a few things that are visible this way)
What I do is put a single import math at the top of my source file, and
use math.sin, and math.cos where needed. Occasionally, I'll use
something like:
from math import sin,cos
at the top, so I know just which symbols I'm defining.
How about:
import math
def f(a):
sin = math.sin
cos = math.cos
return sin(a) + cos(a)
print f(45)
This lets you explicitly use the sin and cos names inside the function,
by defining them at entry to the function.
--
DaveA
[toc] | [prev] | [next] | [standalone]
| From | Mel Wilson <mwilson@the-wire.com> |
|---|---|
| Date | 2012-02-01 13:47 -0500 |
| Message-ID | <jgc1cr$976$1@speranza.aioe.org> |
| In reply to | #19727 |
Dave Angel wrote:
> I tried your experiment using Python 2.7 and Linux 11.04
>
>
> def f(a):
> from math import sin, cos
> return sin(a) + cos(a)
>
> print f(45)
>
> Does what you needed, and neatly. The only name added to the global
> namspace is f, of type function.
>
> I was a bit surprised that using from math import * inside the
> function worked, but it generates a warning:
> olive.py:2: SyntaxWarning: import * only allowed at module level
> def f(a):
I guess they want local symbols in functions to be pre-compiled. Similar to
the way you can't usefully update the dict returned by locals(). Strangely,
I notice that
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def f(x):
... exec x
... exec 'print a'
...
>>> f('a=4')
4
>>>
works, but I really cannot explain why.
Mel.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-02-01 14:49 -0700 |
| Message-ID | <mailman.5325.1328133024.27778.python-list@python.org> |
| In reply to | #19734 |
On Wed, Feb 1, 2012 at 11:47 AM, Mel Wilson <mwilson@the-wire.com> wrote:
> I guess they want local symbols in functions to be pre-compiled. Similar to
> the way you can't usefully update the dict returned by locals(). Strangely,
> I notice that
>
> Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
> [GCC 4.4.3] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> def f(x):
> ... exec x
> ... exec 'print a'
> ...
>>>> f('a=4')
> 4
>>>>
>
> works, but I really cannot explain why.
I am not a dev, but I believe it works because assigning to locals()
and assigning via exec are not the same thing. The problem with
assigning to locals() is that you're fundamentally just setting a
value in a dictionary, and even though it happens to be the locals
dict for the stack frame, Python can't figure out that it should go
and update the value of the optimized local to match. exec, on the
other hand, compiles and executes an actual STORE_NAME operation. Of
course, if the particular local variable hasn't been optimized by the
compiler, then updating locals() works just fine (although you
probably should not rely on this):
>>> def f(x, y):
... locals()[x] = y
... print locals()[x]
... exec 'print ' + x
...
>>> f('a', 42)
42
42
Another interesting thing to note is that the print in your example
doesn't even need to be in a second exec, which I believe works
because the presence of any exec statement disables global variable
optimizations for the function. Compare:
>>> def f(x):
... locals()['a'] = 4
... print a
...
>>> f('pass')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
NameError: global name 'a' is not defined
>>> def f(x):
... locals()['a'] = 4
... print a
... exec x
...
>>> f('pass')
4
And while we're on the subject, here's a nicely obscure syntax error:
>>> def f(x):
... def g():
... print x
... exec x
...
File "<stdin>", line 4
SyntaxError: unqualified exec is not allowed in function 'f' it
contains a nested function with free variables
Cheers,
Ian
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-02-01 15:38 -0700 |
| Message-ID | <mailman.5327.1328135930.27778.python-list@python.org> |
| In reply to | #19734 |
On Wed, Feb 1, 2012 at 3:24 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
> Definitely should rely on it, because in CPython 3 exec does not un-optimize
> the function and assigning to locals() will not actually change the
> functions variables.
Well, the former is not surprising, since exec was changed from a
statement to a built-in. I don't see any difference in the way
locals() behaves, though:
Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> def f(x, y):
... locals()[x] = y
... print(vars())
... exec('print(' + x + ')')
...
>>> f('a', 42)
{'y': 42, 'x': 'a', 'a': 42}
42
That still seems to work as I described it. You couldn't directly
reference it as 'a', though, since the result would be either that it
would try to look up a global with that name, or the compiler would
consider it a local, optimize it, and then you could no longer assign
it via locals().
Cheers,
Ian
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-02-01 14:24 -0800 |
| Message-ID | <mailman.5328.1328136693.27778.python-list@python.org> |
| In reply to | #19734 |
Ian Kelly wrote:
> I am not a dev, but I believe it works because assigning to locals()
> and assigning via exec are not the same thing. The problem with
> assigning to locals() is that you're fundamentally just setting a
> value in a dictionary, and even though it happens to be the locals
> dict for the stack frame, Python can't figure out that it should go
> and update the value of the optimized local to match. exec, on the
> other hand, compiles and executes an actual STORE_NAME operation. Of
> course, if the particular local variable hasn't been optimized by the
> compiler, then updating locals() works just fine (although you
> probably should not rely on this):
>
>>>> def f(x, y):
> ... locals()[x] = y
> ... print locals()[x]
> ... exec 'print ' + x
> ...
>>>> f('a', 42)
> 42
> 42
Definitely should rely on it, because in CPython 3 exec does not
un-optimize the function and assigning to locals() will not actually
change the functions variables.
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-02-01 16:00 -0700 |
| Message-ID | <mailman.5329.1328137234.27778.python-list@python.org> |
| In reply to | #19734 |
On Wed, Feb 1, 2012 at 3:53 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
> --> def f(x, y):
>
> ... locals()[x] = y
> ... print(vars())
> ... exec('print (' + x + ')')
> ... print(x)
> ...
> --> f('a', 42)
>
> {'y': 42, 'x': 'a', 'a': 42}
> 42
> a
>
> Indeed -- the point to keep in mind is that locals() can become out of sync
> with the functions actual variables. Definitely falls in the camp of "if
> you don't know *exactly* what you are doing, do not play this way!"
Sure, but that's not actually out of sync. The argument of your exec
evaluates to 'print (a)'. You get two different results because
you're actually printing two different variables. You can get the
dict temporarily out of sync:
>>> def f(x, y):
... frob = None
... loc = locals()
... loc[x] = y
... print(loc)
... print(locals())
... print(loc)
...
>>> f('frob', 42)
{'y': 42, 'x': 'frob', 'frob': 42, 'loc': {...}}
{'y': 42, 'x': 'frob', 'frob': None, 'loc': {...}}
{'y': 42, 'x': 'frob', 'frob': None, 'loc': {...}}
In this case, 'frob' is updated to 42 in the dict, but the optimized
local is not updated. Calling locals() again refreshes the dict.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-02-01 15:08 -0800 |
| Message-ID | <mailman.5333.1328139369.27778.python-list@python.org> |
| In reply to | #19734 |
Ethan Furman wrote:
> Ian Kelly wrote:
>> I am not a dev, but I believe it works because assigning to locals()
>> and assigning via exec are not the same thing. The problem with
>> assigning to locals() is that you're fundamentally just setting a
>> value in a dictionary, and even though it happens to be the locals
>> dict for the stack frame, Python can't figure out that it should go
>> and update the value of the optimized local to match. exec, on the
>> other hand, compiles and executes an actual STORE_NAME operation. Of
>> course, if the particular local variable hasn't been optimized by the
>> compiler, then updating locals() works just fine (although you
>> probably should not rely on this):
>>
>>>>> def f(x, y):
>> ... locals()[x] = y
>> ... print locals()[x]
>> ... exec 'print ' + x
>> ...
>>>>> f('a', 42)
>> 42
>> 42
>
> Definitely should rely on it, because in CPython 3 exec does not
> un-optimize the function and assigning to locals() will not actually
> change the functions variables.
Ouch, that should have been *not* rely on it; not because it doesn't
work (exec uses locals() if one is not specified), but because it is
easy for the names in the function to get out of sync with the names in
the functions locals() (or __dict__).
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-02-01 16:47 -0700 |
| Message-ID | <mailman.5334.1328140110.27778.python-list@python.org> |
| In reply to | #19734 |
On Wed, Feb 1, 2012 at 4:41 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
> I'm not sure what you mean by temporary:
>
> --> def f(x, y):
>
> ... frob = None
> ... loc = locals()
> ... loc[x] = y
> ... print(loc)
> ... print(locals())
> ... print(loc)
> ... print(locals())
> ...
> -->
> --> f('frob', 19)
> {'y': 19, 'x': 'frob', 'frob': 19}
> {'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
> {'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
> {'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
>
> Seems to be stuck that way.
The first print is the one that is incorrect. It suggests that the
local 'frob' has been changed to 19 as it has in the dict, but the
actual value of the local is still None. The second print on
accurately reflect that.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-02-01 14:53 -0800 |
| Message-ID | <mailman.5335.1328140351.27778.python-list@python.org> |
| In reply to | #19734 |
Ian Kelly wrote:
> On Wed, Feb 1, 2012 at 3:24 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
>> Definitely should rely on it, because in CPython 3 exec does not un-optimize
>> the function and assigning to locals() will not actually change the
>> functions variables.
>
> Well, the former is not surprising, since exec was changed from a
> statement to a built-in. I don't see any difference in the way
> locals() behaves, though:
>
> Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win
> 32
> Type "help", "copyright", "credits" or "license" for more information.
>>>> def f(x, y):
> ... locals()[x] = y
> ... print(vars())
> ... exec('print(' + x + ')')
> ...
>>>> f('a', 42)
> {'y': 42, 'x': 'a', 'a': 42}
> 42
>
> That still seems to work as I described it. You couldn't directly
> reference it as 'a', though, since the result would be either that it
> would try to look up a global with that name, or the compiler would
> consider it a local, optimize it, and then you could no longer assign
> it via locals().
>
> Cheers,
> Ian
--> def f(x, y):
... locals()[x] = y
... print(vars())
... exec('print (' + x + ')')
... print(x)
...
--> f('a', 42)
{'y': 42, 'x': 'a', 'a': 42}
42
a
Indeed -- the point to keep in mind is that locals() can become out of
sync with the functions actual variables. Definitely falls in the camp
of "if you don't know *exactly* what you are doing, do not play this way!"
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-02-02 00:34 +0000 |
| Message-ID | <4f29da30$0$29989$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #19756 |
On Wed, 01 Feb 2012 14:53:09 -0800, Ethan Furman wrote: > Indeed -- the point to keep in mind is that locals() can become out of > sync with the functions actual variables. Definitely falls in the camp > of "if you don't know *exactly* what you are doing, do not play this > way!" And if you *do* know exactly what you are doing, you will probably decide not to play this way also! -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-02-01 15:59 -0800 |
| Message-ID | <mailman.5336.1328140417.27778.python-list@python.org> |
| In reply to | #19734 |
Ian Kelly wrote:
> On Wed, Feb 1, 2012 at 4:41 PM, Ethan Furman <ethan@stoneleaf.us> wrote:
>> I'm not sure what you mean by temporary:
>>
>> --> def f(x, y):
>>
>> ... frob = None
>> ... loc = locals()
>> ... loc[x] = y
>> ... print(loc)
>> ... print(locals())
>> ... print(loc)
>> ... print(locals())
>> ...
>> -->
>> --> f('frob', 19)
>> {'y': 19, 'x': 'frob', 'frob': 19}
>> {'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
>> {'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
>> {'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
>>
>> Seems to be stuck that way.
>
> The first print is the one that is incorrect. It suggests that the
> local 'frob' has been changed to 19 as it has in the dict, but the
> actual value of the local is still None. The second print on
> accurately reflect that.
Ah. Thanks for the explanations.
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-02-01 15:41 -0800 |
| Message-ID | <mailman.5339.1328142880.27778.python-list@python.org> |
| In reply to | #19734 |
Ian Kelly wrote:
> Sure, but that's not actually out of sync. The argument of your exec
> evaluates to 'print (a)'. You get two different results because
> you're actually printing two different variables.
Ah -- thanks, I missed that.
> You can get the dict temporarily out of sync:
>
>>>> def f(x, y):
> ... frob = None
> ... loc = locals()
> ... loc[x] = y
> ... print(loc)
> ... print(locals())
> ... print(loc)
> ...
>>>> f('frob', 42)
> {'y': 42, 'x': 'frob', 'frob': 42, 'loc': {...}}
> {'y': 42, 'x': 'frob', 'frob': None, 'loc': {...}}
> {'y': 42, 'x': 'frob', 'frob': None, 'loc': {...}}
>
> In this case, 'frob' is updated to 42 in the dict, but the optimized
> local is not updated. Calling locals() again refreshes the dict.
I'm not sure what you mean by temporary:
--> def f(x, y):
... frob = None
... loc = locals()
... loc[x] = y
... print(loc)
... print(locals())
... print(loc)
... print(locals())
...
-->
--> f('frob', 19)
{'y': 19, 'x': 'frob', 'frob': 19}
{'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
{'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
{'y': 19, 'x': 'frob', 'frob': None, 'loc': {...}}
Seems to be stuck that way.
Here is a better example I was thinking of:
--> def f(x, y):
... locals()[x] = y
... locals()['x'] = 17
... print(locals())
... print(x)
... print(y)
...
--> f('a', 42)
{'y': 42, 'x': 'a', 'a': 42}
a
42
So locals() was updated with 'a', but not with the assignment to 'x'.
And of course, if we tried to 'print(a)' we'd get a NameError.
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-02-01 15:51 -0800 |
| Message-ID | <mailman.5340.1328143879.27778.python-list@python.org> |
| In reply to | #19734 |
Ethan Furman wrote:
> Ethan Furman wrote:
>> Ian Kelly wrote:
>>> I am not a dev, but I believe it works because assigning to locals()
>>> and assigning via exec are not the same thing. The problem with
>>> assigning to locals() is that you're fundamentally just setting a
>>> value in a dictionary, and even though it happens to be the locals
>>> dict for the stack frame, Python can't figure out that it should go
>>> and update the value of the optimized local to match. exec, on the
>>> other hand, compiles and executes an actual STORE_NAME operation. Of
>>> course, if the particular local variable hasn't been optimized by the
>>> compiler, then updating locals() works just fine (although you
>>> probably should not rely on this):
>>>
>>>>>> def f(x, y):
>>> ... locals()[x] = y
>>> ... print locals()[x]
>>> ... exec 'print ' + x
>>> ...
>>>>>> f('a', 42)
>>> 42
>>> 42
>>
>> Definitely should rely on it, because in CPython 3 exec does not
>> un-optimize the function and assigning to locals() will not actually
>> change the functions variables.
>
>
> Ouch, that should have been *not* rely on it; not because it doesn't
> work (exec uses locals() if one is not specified), but because it is
> easy for the names in the function to get out of sync with the names in
> the functions locals() (or __dict__).
I should stop answering now :( Ignore the __dict__ comment, it is
incorrect.
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Chris Rebert <clp2@rebertia.com> |
|---|---|
| Date | 2012-02-01 09:38 -0800 |
| Message-ID | <mailman.5312.1328117942.27778.python-list@python.org> |
| In reply to | #19721 |
On Wed, Feb 1, 2012 at 9:11 AM, Olive <diolu@bigfoot.com> wrote:
> I am learning python and maybe this is obvious but I have not been able
> to see a solution. What I would like to do is to be able to execute a
> function within the namespace I would have obtained with from <module>
> import *
>
> For example if I write:
>
> def f(a):
> return sin(a)+cos(a)
>
> I could then do:
>
> from math import *
>
> f(5)
>
> But I have polluted my global namespace with all what's defined in
> math. I would like to be able to do something like "from math import *"
> at the f level alone.
>
> The main reason for this is the sympy module for CAS (computer algebra).
> It reimplement a lot of functions and define all the letters as symbolic
> variables. Writing sympy.<function> everywhere is inconvenient.
> Importing all the symbols in the global namespace would lead to name
> clash. It would be nice if I could import all the sympy names but for a
> given function only.
Don't think that's possible. Best alternative I can think of would be:
import sympy as s
def f(a):
return s.sin(a) + s.cos(a)
Cheers,
Chris
[toc] | [prev] | [next] | [standalone]
| From | Christian Heimes <lists@cheimes.de> |
|---|---|
| Date | 2012-02-01 18:50 +0100 |
| Message-ID | <mailman.5314.1328118666.27778.python-list@python.org> |
| In reply to | #19721 |
Am 01.02.2012 18:36, schrieb Dave Angel: > def f(a): > from math import sin, cos > return sin(a) + cos(a) > > print f(45) > > Does what you needed, and neatly. The only name added to the global > namspace is f, of type function. I recommend against this approach. It's slightly slower and the global import lock will cause trouble if you start using threads. Christian
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web