By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,589 Members | 1,555 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,589 IT Pros & Developers. It's quick & easy.

variables exist

P: n/a
how testing if a variable exists in python as isset in php??

thanks
Jul 18 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
"fabian" wrote:
how testing if a variable exists in python as isset in php??


try:
variable
except NameError:
print "variable not set"

but that is really lousy Python; better make sure you always assign to
all variables, and use None (or another suitable value) to mark that some
variable has no meaningful content right now.

that is, instead of

if condition:
variable = 1

...

try:
variable
except NameError:
....

write

variable = None

if condition:
variable = 1

...

if variable is None:
print "variable not set"

</F>

Jul 18 '05 #2

P: n/a
try:
myVariable
except NameError:
print "Not bound"
else:
print "Bound"

If you want to distinguish between the local an the global environment:

if globals().has_key( "myVariable" ):
...

versus

if locals().has_key( ".....
HTH,
Gerald

fabian schrieb:
how testing if a variable exists in python as isset in php??

thanks


--
GPG-Key: http://keyserver.veridis.com:11371/search?q=0xA140D634

Jul 18 '05 #3

P: n/a
Fredrik Lundh said unto the world upon 2005-04-11 10:14:
"fabian" wrote:
how testing if a variable exists in python as isset in php??

try:
variable
except NameError:
print "variable not set"

but that is really lousy Python; better make sure you always assign to
all variables, and use None (or another suitable value) to mark that some
variable has no meaningful content right now.

that is, instead of


<SNIP full try/except example>
write

variable = None

if condition:
variable = 1

...

if variable is None:
print "variable not set"

</F>

Hi Fredrik and all,

I'm a hobbyist and still learning, but the claim the try/except is
"lousy Python" surprise me a bit. The try/except way seems like an
instance of "Easier to ask Forgiveness than Permission", and my sense
is that in 95% of cases that approach is widely considered more
Pythonic than LBYL (of which the suggested idiom seems reminiscent).

As it happens, most of my code does preset names to None, but reading
this thread made me wonder. Are you suggesting setting to None is
better as it makes explicit that there is nothing there, but this may
change in the future? (This is why I do it.) Or for some other reason?

I have no partisan interests either way; I'm just trying to
understand. Thanks and best,

Brian vdB
Jul 18 '05 #4

P: n/a
Brian van den Broek wrote:
Fredrik Lundh said unto the world upon 2005-04-11 10:14:
"fabian" wrote:
how testing if a variable exists in python as isset in php??


try:
variable
except NameError:
print "variable not set"

but that is really lousy Python; better make sure you always assign to
all variables, and use None (or another suitable value) to mark that some
variable has no meaningful content right now.

that is, instead of

<SNIP full try/except example>
write

variable = None
if condition:
variable = 1
...
if variable is None:
print "variable not set"


I'm a hobbyist and still learning, but the claim the try/except is
"lousy Python" surprise me a bit. The try/except way seems like an
instance of "Easier to ask Forgiveness than Permission", and my sense
is that in 95% of cases that approach is widely considered more Pythonic
than LBYL (of which the suggested idiom seems reminiscent).

As it happens, most of my code does preset names to None, but reading
this thread made me wonder. Are you suggesting setting to None is
better as it makes explicit that there is nothing there, but this may
change in the future? (This is why I do it.) Or for some other reason?


I had a similar reaction to Fredrik's statement. In general, I wouldn't
call a try/except solution lousy style, as long as the path through
except was sufficiently "exceptional". That is, for code like:

if condition_that_happens_99_percent_of_the_time:
variable = 1
try:
variable
except NameError:
print "variable not set"

seems perfectly reasonable to me, because the exception is caught in the
*exceptional* case. However, if one case isn't clearly the exceptional
one, then it probably doesn't makes sense to use an exception, and I'd
write it like:

variable = None
if condition_that_happens_40_percent_of_the_time:
variable = 1
...
if variable is None:
print "variable not set"

Actually, I typically refactor my code so that I can write situations
like this as:

if condition_that_happens_40_percent_of_the_time:
variable = 1
...
else:
print "variable not set"

But the point still stands. If the variable being unset really is an
exceptional case, use an exception. If it's not, then an if/else block
is probably the better way to go.

STeVe
Jul 18 '05 #5

P: n/a

"Brian van den Broek" <bv****@po-box.mcgill.ca> wrote in message
news:ma**************************************@pyth on.org...
I'm a hobbyist and still learning, but the claim the try/except is
"lousy Python" surprise me a bit.


I think it wasn't the use of try/except as such. It's more that
if you're the developer you ought to know whether variables
are defined or not. It might be a sign you're using global
variables more often than would be considered good style in
Python.
Jul 18 '05 #6

P: n/a
Richard Brodie said unto the world upon 2005-04-12 04:56:
"Brian van den Broek" <bv****@po-box.mcgill.ca> wrote in message
news:ma**************************************@pyth on.org...

I'm a hobbyist and still learning, but the claim the try/except is
"lousy Python" surprise me a bit.

I think it wasn't the use of try/except as such. It's more that
if you're the developer you ought to know whether variables
are defined or not. It might be a sign you're using global
variables more often than would be considered good style in
Python.


Richard and STeVe,

thanks for the replies :-)

I see your point, Richard. Though where it has come up for me most
often is code internal to a class, where I only need a "real" value
for a class attribute in some cases, depending upon the inputs to the
class __init__. "Globals are bad" is one lesson I have learned :-)

STeVe stressed that the try/except solution is only really appropriate
for cases where the failure to have the variable defined is quite
rare. Even though wary of "the root of all evil ... " that seems a
good reminder. Thanks.

Best to all,

Brian vdB

Jul 18 '05 #7

P: n/a
Brian van den Broek wrote:
... STeVe stressed that the try/except solution is only really appropriate
for cases where the failure to have the variable defined is quite rare.


Beware: C++ and Java have an immense overhead for exceptions. Python
has a very lightweight exception mechanism. You should _very_seldom_
choose exceptions or not on the basis of performance without measuring
the actual use; you are sure to be surprised.

Structure your code to be easiest to understand. _If_ it is too slow,
investigate ways to improve its performance. The usual way is to
build better data structures and use better algorithms. Only in the
core of a frequently used inner loop should you even care about the
cost of exceptions. Even then, you can often lift the exception
handler around the loop and recover the most necessary performance.

--Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #8

P: n/a
Scott David Daniels wrote:
... STeVe stressed that the try/except solution is only really appropriate
for cases where the failure to have the variable defined is quite rare.


Beware: C++ and Java have an immense overhead for exceptions. Python
has a very lightweight exception mechanism. You should _very_seldom_
choose exceptions or not on the basis of performance without measuring
the actual use; you are sure to be surprised.

Structure your code to be easiest to understand. _If_ it is too slow,
investigate ways to improve its performance. The usual way is to
build better data structures and use better algorithms. Only in the
core of a frequently used inner loop should you even care about the
cost of exceptions.


you haven't really read this thread, have you?

</F>

Jul 18 '05 #9

P: n/a
Scott David Daniels wrote:
Brian van den Broek wrote:
... STeVe stressed that the try/except solution is only really
appropriate for cases where the failure to have the variable defined
is quite rare.


Beware: C++ and Java have an immense overhead for exceptions. Python
has a very lightweight exception mechanism. You should _very_seldom_
choose exceptions or not on the basis of performance without measuring
the actual use; you are sure to be surprised.


I'll just point out that I wasn't suggesting that try/except should be
used as an optimization, but that it should be used when *exceptional*
behavior is encountered. Using try/except for non-exceptional behavior
can be confusing for readers of your code who assume the normal
semantics. Just to make sure my point is clear, a great case for
try/except is with dictionaries, e.g.
try:
v = d[k]
except KeyError:
...
In this case, the key not being in the dictionary clearly makes sense as
exceptional behavior because there's no reason to have a dictionary if
there's nothing in it. Similarly, try/excepts are great for dealing
with duck typing issues, e.g.:
def f(mapping)
try:
itervalues = mapping.itervalues
except AttributeError:
values = (mapping[k] for k in mapping)
else:
values = itervalues()
...
Again, the point is that the AttributeError is the *exceptional*
behavior; f expects a mapping with an itervalues method, and if it
receives an object that doesn't have one, it has to deal with the
exceptional case of replacing that method.

Anyway, I hope that clarifies my intentions. Use try/except when it
makes sense to talk about something as being *exceptional* behavior. If
it doesn't, you should probably use if/else.

STeVe

P.S. That said, there *are* performance differences. Here's a test that
shows how try/except can be more costly the more often the except clause
is reached:

----------------------------------------------------------------------
import timeit

def ifelse(mapping, key):
if key in mapping:
return mapping[key]
else:
return None

def tryexcept(mapping, key):
try:
return mapping[key]
except KeyError:
return None

setup_code = """\
from __main__ import %s as func
mapping = %s
keys = %s
"""

test_code = '[func(mapping, key) for key in keys]'

def get_time(func, mapping, keys):
return timeit.Timer(test_code, setup_code % (
func.__name__, mapping, keys)).timeit(1000)

if __name__ == '__main__':
N = 1000
mapping = dict((i, i**2) for i in xrange(N))
for i in [0, 1, 2, 4, 8]:
number_missing = i*N/100
keys = range(number_missing, N + number_missing)
ifelse_time, tryexcept_time = (get_time(func, mapping, keys)
for func in [ifelse, tryexcept])
result = ['%3i%%' % (100*number_missing/N)]
for time, func in sorted([(ifelse_time, ifelse),
(tryexcept_time, tryexcept)]):
result.extend(['%.4f' % time, '%10s' % func.__name__])
print '\t'.join(result)
----------------------------------------------------------------------

And the results I get from running it:

[D:\Steve]$ test.py
0% 0.8467 tryexcept 0.9415 ifelse
1% 0.9374 tryexcept 0.9430 ifelse
2% 0.9499 ifelse 1.0375 tryexcept
4% 0.9580 ifelse 1.1576 tryexcept
8% 0.9333 ifelse 1.4187 tryexcept

Thus try/except is better when almost all of the keys can be found in
the dict, but as soon as even 2% of the keys cannot, if/else is the more
efficient solution. This is toy data, so obviously YMMV. But if you
use try/except for a very frequent occurrence instead of an exceptional
one, you may notice a performance hit.
Jul 18 '05 #10

P: n/a
In article <96**************************@posting.google.com >,
fa***********@free.fr (fabian) wrote:
how testing if a variable exists in python as isset in php??


Would the following be a satisfactory implementation?

def isset(varname, lloc = locals()):
return varname in lloc or varname in globals()

I believe this works as desired:
x = 5
def f(y): ... z = 10
... print isset('z') ## ==> True
... print isset('y') ## ==> True
... print isset('x') ## ==> True
...

Tests: f(1) ## As shown above
print isset('z') ## ==> False
print isset('y') ## ==> False
print isset('x') ## ==> True
print isset('varname') ## ==> False
print isset('lloc') ## ==> False
lloc = "foo!"
print isset('lloc') ## ==> True


Perhaps this is not the most elegant solution, but I believe it handles
scoping correctly.

-M

--
Michael J. Fromberger | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
Jul 19 '05 #11

P: n/a
Michael J. Fromberger wrote:
Would the following be a satisfactory implementation?

def isset(varname, lloc = locals()):
return varname in lloc or varname in globals()

I believe this works as desired:
>>> x = 5
>>> def f(y): ... z = 10
... print isset('z') ## ==> True
... print isset('y') ## ==> True
... print isset('x') ## ==> True
...

Tests: >>> f(1) ## As shown above
No, try it again in a fresh interpreter:
def isset(name, loc=locals()): .... return name in loc or name in globals()
.... x = 5
def f(y): .... z = 10
.... print isset("x"), isset("y"), isset("z")
.... f(42) True False False


It may seem from the above that at least the global variable "x" is found
correctly, but beware, the global namespace where isset() is defined is
searched, not the one where it is called. Untested:

def isset(name):
frame = sys._getframe(1)
return name in frame.f_locals or name in frame.f_globals

might work, but is too magic for my taste.

Peter

Jul 19 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.