Determine if variable is defined in Python

790,958

Solution 1

try:
    thevariable
except NameError:
    print("well, it WASN'T defined after all!")
else:
    print("sure, it was defined.")

Solution 2

'a' in vars() or 'a' in globals()

if you want to be pedantic, you can check the builtins too
'a' in vars(__builtins__)

Solution 3

I think it's better to avoid the situation. It's cleaner and clearer to write:

a = None
if condition:
    a = 42

Solution 4

try:
    a # does a exist in the current namespace
except NameError:
    a = 10 # nope

Solution 5

For this particular case it's better to do a = None instead of del a. This will decrement reference count to object a was (if any) assigned to and won't fail when a is not defined. Note, that del statement doesn't call destructor of an object directly, but unbind it from variable. Destructor of object is called when reference count became zero.

Share:
790,958
user102008
Author by

user102008

Updated on January 31, 2020

Comments

  • user102008
    user102008 over 4 years

    How do you know whether a variable has been set at a particular place in the code at runtime? This is not always obvious because (1) the variable could be conditionally set, and (2) the variable could be conditionally deleted. I'm looking for something like defined() in Perl or isset() in PHP or defined? in Ruby.

    if condition:
        a = 42
    
    # is "a" defined here?
    
    if other_condition:
        del a
    
    # is "a" defined here?
    
  • John La Rooy
    John La Rooy over 14 years
    If you like to do it that way you should make the initial value unique so you can distinguish from something setting a to None ie. UNDEFINED=object();a=UNDEFINED then you can test with a is not UNDEFINED
  • Denis Otkidach
    Denis Otkidach over 14 years
    @Aaron: There are many cases when you don't know whether variable is defined. You can refactor code to avoid this in many, but not all cases. Alex's solution is correct and it the best when refactoing is not possible for some reasons. There is not much information in the question, so I believe only person asked it can select the best way to handle his case.
  • Alex Martelli
    Alex Martelli over 14 years
    @Aaron, "should" is a 4-letter word -- e.g. no driver "should" ever exceed the speed limit, but that doesn't mean you don't take all proper and needed precautions against those who nevertheless do. Maintaining fragile, undertested legacy code with somewhat-broken design that you inherited from somebody else is a fact of life, and those who can only think of big-bang rewriting from scratch rather than cautiously and incrementally need to re-read Joel's 9-years-old essay joelonsoftware.com/articles/fog0000000069.html .
  • sc45
    sc45 over 14 years
    @S.Lott People use it to maintain backwards compatibility. Search for NameError in Python 3.1 source code. There are many instances where "try: var_name except NameError: something_else" is used. Here are a couple of place where it is used: CSV (svn.python.org/projects/python/trunk/Lib/csv.py) library and in the ElementTree library (svn.python.org/projects/python/trunk/Lib/xml/etree/…).
  • Devin Jeanpierre
    Devin Jeanpierre over 14 years
    This is a common use of None. It's literally the semantic meaning of None-- it's nothing, nada, zip. It exists, but has "no value". Using a non-None value is useful if None can come up in an assignment and so on, but this is not so common that avoiding None should be standard practice. For example, in the question, a would only ever be 42 or undefined. Changing undefined to having a value of None results in no loss of information.
  • e-satis
    e-satis about 14 years
    This debate is much more interesting that the answer itself, which by the way is 100% correct and let you handle poor legacy code elegantly.
  • 0atman
    0atman over 13 years
    This should be the answer I believe. see stackoverflow.com/questions/843277/…
  • andreabedini
    andreabedini over 13 years
    it depends on the context, in a scripting environment, for example, it's perfectly fine to check if a variable is defined or not, and ad. es. give it a default value. my 2c.
  • Yarin
    Yarin about 12 years
    @S.Lott - What about a variable in a view template, where it's up to the including code to set the variable? How would you ensure a defined variable in those situations?
  • Pitto
    Pitto over 11 years
    Variables can also be dynamically defined and I don't want my script to stop working just because the variable gets correctly defined only if "x" happens. Upvote!
  • SilentSteel
    SilentSteel about 11 years
    Note: If it's a class attribute, you need to use try: self.MyMissingVar except AttributeError: print 'It's not there!'
  • Mitchell Model
    Mitchell Model about 11 years
    Much of the discussion in the other answers assumes that the problem is how to tell whether a symbol has an initial value, whereas the OP made it clear that the question is really whether the symbol has any value at all. None is a value, so a symbol whose value is None DOES have a value "at all".
  • Mitchell Model
    Mitchell Model about 11 years
    [continuing] That is why using a try or checking globals() is necessary. Example: You have a file that performs significant initialization computation whose results you want to assign to global symbols. You want to be able to execfile/exec (Python 2/3) the file from any of a number of modules, some perhaps used in more than one program. However, you only want the initialization performed once during a program's execution. Solution: put the execfile/exec in as many places as you want and wrap the file's contents in a conditional that tests whether one of the symbols it defines has a value.
  • FizxMike
    FizxMike over 10 years
    This is THE way, not sure why people think using a LONG and DIRTY try/except construct to get this done. ALSO this is very useful when using keyword args in class member functions where you don't want to hard-code the default values into the parameter list (you just define the default value as a class member).
  • einpoklum
    einpoklum about 9 years
    Exceptions should be reserved for exceptional cases, not for use as the bastard brother of 'if' :-(
  • einpoklum
    einpoklum about 9 years
    See also a general discussion on when to use exceptions here on SO.
  • einpoklum
    einpoklum about 9 years
    Exceptions should only be used in exceptional cases. See this discussion
  • Martin Smith
    Martin Smith about 9 years
    Meta discussion linking to this answer meta.stackoverflow.com/q/289938/73226
  • Alex Martelli
    Alex Martelli about 9 years
    @einpoklum, Python uses exception StopIteration within just about every for statement -- that's how an iterator lets it known that it's all done. And of course, it is far from "an exceptional case" for iteration to be done -- indeed, one expects most iterations to terminate. Thus, obviously, your opinions on how exceptions "should" be used are not correctly applicable to Python (other languages have different pragmatics and the question cannot be properly treated as "language agnostic" as in the Q you point to).
  • sdcvvc
    sdcvvc about 9 years
    @einpoklum This is true for most languages, but in Python exceptions are used more often, see e.g. stackoverflow.com/questions/3086806
  • einpoklum
    einpoklum about 9 years
    Hmm, strange but true, apparently. I still think that's not a Good Idea (TM) but, well, can't argue with community customs.
  • Nicklas Börjesson
    Nicklas Börjesson about 9 years
    I agree with @AlexMartelli: The ability to have undefined variables is a feature in Python. As any features, it has some use cases where it is more or less appropriate. But it it certainly not never appropriate. Testing for it being defined or not is not less strange than testing for the existence of a file. And Python being a lot about duck typing, using an exception makes perfect sense. And by the way, exceptions are the bastard brothers of if:s.
  • robert
    robert over 8 years
    This is a very idiomatic answer. There is a strong use case here for maps; for example, if "prop2" in {"prop0": None, "prop1": None}:
  • Shadur
    Shadur about 8 years
    @habnabit Easy refutal: I'm using iniparse to load a config file but want to make sure certain variables were set, or the program can't continue.
  • Taywee
    Taywee about 8 years
    @DevinJeanpierre That's not necessarily true. If you want to create some client library for a JSON API that treats a null value as different from an unspecified value (eg. None sets the actual JSON value to null, whereas an unspecified leaves it out of the JSON message entirely, which makes the API use a default or calculate from other attributes), you need to either differentiate None from Undefined, or None from JSON null. It's incredibly short-sighted to think that None can't or shouldn't ever be used as distinct from a value that is explicitly unspecified or undefined.
  • Devin Jeanpierre
    Devin Jeanpierre almost 8 years
    @Taywee sure. "Using a non-None value is useful if None can come up in an assignment and so on, but this is not so common that avoiding None should be standard practice." If a non-None value can come up, then None is not acceptable, and this whole pattern is error-prone.
  • fisk
    fisk almost 8 years
    stumbled across this problem while using pyspark with Jupiter (which DOES define SparkContext as sc for you) and Mesos, which does not. This is why we need this sometimes.
  • AatG
    AatG almost 8 years
    python is used for interactive data analysis in say Jupyter notebooks. In this case, it's great to be able to add a check for whether a variable is defined or not before potentially reloading or recomputing a costly variable simply because you changed another portion of code in the cell and reevaluated it.
  • habnabit
    habnabit over 7 years
    @Shadur irrelevant; iniparse doesn't set variables.
  • Tim S.
    Tim S. about 7 years
    Providing a default value (which is what this answer is doing) is far different than testing the existence of a variable. There may be much overlap in the use cases, but if you want to see if something has been defined, you'll never know with this method.
  • aaaantoine
    aaaantoine almost 7 years
    This answer also works for detecting members other than variables, such as functions, classes, and modules.
  • Ron Kalian
    Ron Kalian over 6 years
    Better use the if 'a' in vars() or 'a' in globals() solution mentioned above, which does not require an exception
  • eric
    eric over 6 years
    try/except is what you do in python. what is a code smell in one language is a feature in another.
  • Admin
    Admin about 6 years
    As of today — June 2018: I don't think vars(__builtin__) still works (either for Python 2 or 3). I believe vars(__builtins__) (mind the plural ;-)) should be used for both versions now (tested on: Python 2.7.10 and Python 3.6.1).
  • Mawg says reinstate Monica
    Mawg says reinstate Monica almost 6 years
    Then perhaps the connection close should not be done in the finally?
  • AndresVia
    AndresVia over 5 years
    Why not locals() too, why not dir()?
  • KeyC0de
    KeyC0de over 4 years
    @AndresVia globals() is a superset of locals().
  • Francesco
    Francesco almost 4 years
    This should be the accepted answer. It looks much better when embedded into an if structure that checks for other conditions.
  • eric
    eric over 3 years
    @einpoklum in python try/except is not exceptional it is as friendly a part of program control as if or for.
  • Quin
    Quin about 2 years
    I like this one better: a = globals().get('a','@') Thanks @Bachsau