How to set a Python variable to 'undefined'?

106,936

Solution 1

You can delete a global name x using

del x

Python doesn't have "variables" in the sense C or Java have. In Python, a variable is just a tag you can apply to any object, as opposed to a name refencing some fixed memory location.

Deleting doesn't necessarily remove the object the name pointed to.

Solution 2

You probably want to set it to None.

variable = None

Check if variable is "defined"

is_defined = variable is not None

You could delete the variable, but it is not really pythonic.

variable = 1
del variable
try:
    print(variable)
except (NameError, AttributeError):
    # AttributeError if you are using "del obj.variable" and "print(obj.variable)"
    print('variable does not exist')

Having to catch a NameError is not very conventional, so setting the variable to None is typically preferred.

Solution 3

If you want to be able to test its 'undefined state', you should set it to None :

variable = None

and test with

if variable is None: 

If you want to clean stuff, you can delete it, del variable but that should be task of the garbage collector.

Solution 4

In light of the OP's comments:

# check if the variable is undefined
try:
    x
# if it is undefined, initialize it
except NameError:
    x = 1

And like the rest said, you can delete a defined variable using the del keyword.

Solution 5

Here is a case when you actually want undef: function arguments that can have any value (including None), but we still need to know if the value was provided or not.

For example:

class Foo:
    """
    Some container class.
    """

    def pop(self, name, default):
        """
        Delete `name` from the container and return its value.

        :param name: A string containing the name associated with the
            value to delete and return.
        :param default: If `name` doesn't exist in the container, return
            `default`. If `default` is not given, a `KeyError` exception is
            raised.
        """
        try:
            return self._get_and_delete_value_for(name)
        except GetHasFailedError:
            if default is undefined:
                raise KeyError(name)
            else:
                return default

This is very much like dict.pop, and you need to know if default was given. One could fake that with *args, **kwargs, but that gets messy quickly, and having undef would really help.

IMO, the easiest approach for that is this:

_undef = object()


class Foo:
    """
    Some container class.
    """

    def pop(self, name, default=_undef):
        """
        Delete `name` from the container and return its value.

        :param name: A string containing the name associated with the
            value to delete and return.
        :param default: If `name` doesn't exist in the container, return
            `default`. If `default` is not given, a `KeyError` exception is
            raised.
        """
        try:
            return self._get_and_delete_value_for(name)
        except GetHasFailedError:
            if default is _undef:
                raise KeyError(name)
            else:
                return default

The leading underscore implies that the variable is private to the module and shouldn't be used outside of it, which suggests that _undef should not be used as an argument value, making it a good detector for "this value is undefined".

Share:
106,936
Duke Dougal
Author by

Duke Dougal

Updated on August 03, 2021

Comments

  • Duke Dougal
    Duke Dougal almost 3 years

    In Python 3, I have a global variable which starts as "undefined".

    I then set it to something.

    Is there a way to return that variable to a state of "undefined"?

    @martijnpieters

    EDIT - this shows how a global variable starts in a state of undefined.

    Python 2.7.5+ (default, Feb 27 2014, 19:37:08) 
    [GCC 4.8.1] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'x' is not defined
    >>> global x
    >>> x
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'x' is not defined
    >>> 
    
  • user2357112
    user2357112 almost 10 years
    Note that if you stick this in a function, you'll just get an UnboundLocalError unless the function declares that it's referring to the global x with the line global x.
  • Duke Dougal
    Duke Dougal almost 10 years
    @justinengel (at)guillaume (at)damienfrancois None is not the same as undefined.
  • Duke Dougal
    Duke Dougal almost 10 years
    This answer tests to see if the variable is in an undefined state.
  • justengel
    justengel over 9 years
    @DukeDougal We suggest using None instead, because the idea of an undefined variable is not "pythonic". Python programmers are very particular about how the language is used that's why PEP's were made. Pylint is what most python programmers use to check code syntax, and it will show an undefined variable as bad practice. opensourcehacker.com/2012/10/17/…
  • octopusgrabbus
    octopusgrabbus almost 8 years
    Thanks. I have exactly this problem, referencing something that was never set. It's set at the top of the function now.
  • Sapphire_Brick
    Sapphire_Brick over 4 years
    Isn't it still bad practice to be changing your mind about variables at all, in terms of pythonicness?
  • parvus
    parvus over 2 years
    Why is del not effective?
  • Rodrigo Alvaro Santo SD 6
    Rodrigo Alvaro Santo SD 6 over 2 years
    because del x will return an error, not undefined
  • parvus
    parvus over 2 years
    Which is per my understanding exactly what was asked for.
  • LogicDaemon
    LogicDaemon almost 2 years
    using a string is bad idea. This string will be comparable with other strings, and for example, x > "0" is true after the code in the answer, same as bool(x) (code after if x: will execute)