6

Is there a way to check if a class has been defined/exists? I have different options on a menu, and some of them require inherited variables, so if you try to select that function before you have set the variables, it crashes. My class is called Gen0, and I started it by simply putting

class Gen0():

Followed by the rest of the code to set the variables. For context, I am doing a population model, so the initial values need to be set (option 1) before displaying (option 2), using (option 3) or exporting (option 4) them.

Chathuranga Chandrasekara
  • 20,548
  • 30
  • 97
  • 138
Ollie
  • 107
  • 1
  • 1
  • 9

5 Answers5

18

Your situation is not entirely clear, so I'm just going to answer the question "Is there a way to check if a class has been defined/exists?"

Yes, there are ways to check if a class has been defined in the current scope. I'll go through a few.

1. It's Better to Ask Forgiveness Than Permission

Just try to use it!

try:
    var = MyClass()
except NameError:
    # name 'MyClass' is not defined
    ...

This is probably the most Pythonic method (aside from just being sure you have the class imported/defined).

2. Look Through Current Scope

Everything in the current scope is given by dir(). Of course, this won't handle things that are imported! (Unless they are imported directly.)

if not 'MyClass' in dir():
    # your class is not defined in the current scope
    ...

3. Inspect a Module's Contents

Perhaps you want to see if the class is defined within a specific module, my_module. So:

import my_module
import inspect

if not 'MyClass' in inspect.getmembers(my_module):
    # 'MyClass' does not exist in 'my_module'
    ...

Now, it's worth pointing out that if at any point you are using these sorts of things in production code, you're probably writing your code poorly. You should always know which classes are in scope at any given point. After all, that's why we have import statements and definitions. I'd recommend you clean up your question with more example code to receive better responses.

Pierce Darragh
  • 2,072
  • 2
  • 16
  • 29
0

Instead of checking whether the variable exists, you might want to go for a EAFP solution. For example:

try:
   print(var)
except NameError:
   var = 2
   print(var)

If var is not defined before this piece of code, it will assign it to 2 and print it.

Community
  • 1
  • 1
Douglas Vieira
  • 183
  • 1
  • 7
  • try: class Display(Gen0): print(Gen0.juvenile_population) except NameError: pass this didn't work - any further ideas? – Ollie Jul 03 '16 at 16:07
  • 1
    @ollie, you only use the `class` keyword when defining a class, not when you are using it. I think you should read up a little more about the syntax otherwise you're going to get very frustrated with lots of errors. Start here: http://www.tutorialspoint.com/python/python_classes_objects.htm – Resonance Jul 03 '16 at 17:20
0

I'm guessing gen0 is defined something like this:

class gen0:
    pass

as opposed to initialising the attributes in your class on object creation

class gen0:
    def __init__(self):
        # this function will be run when you call "g = gen0()"
        # in the main body of you code. and the following properties 
        # will be set on object "g"
        self.juvenile_population = 0
        self.juv.... etc

so I'm also guessing that you are getting an AttributeError when you try to access something like juvenile_population before it is set.

Initialising your classes properly is the best way to do object orientated programming IMHO.

However the literal answer to your question would be:

 g = gen0()
 if "juvenile_population" in dir(g):
      .... etc

Note this checks only that the object has the juvenile_population attribute, you would need a lot more of these statements to check every attribute, similarly you could use the EAFP approach in Douglas' answer but again that's going to bulk out your code a lot with try statements.

Resonance
  • 3,359
  • 2
  • 16
  • 20
  • If I were to properly initialise my attributes, how would I then check whether the class variables exist? Is it any different, or is it just good practise to initialise them? – Ollie Jul 03 '16 at 16:15
  • Either set them to a sensible default value to start with, like to `self.vari = None`. Then you can use `if g.vari: ....`. – Resonance Jul 03 '16 at 16:30
0

Recently I've run into the same question writing my custom protocol. This is my solution, no extra modules, no evals used:

import handlers

# ... skip ...
# create example request
request = {'message': 'Test', 'param1': True, 'param2': False}

Handler = getattr(handlers, '__dict__', {}).get(request.get('message'))
if not Handler:
  raise InvalidRequestException('Invalid request')

handler = Handler(request)
# process request...

# ... skip ...

It doesn't distinguish classes/functions – you should make an additional check.

dmig
  • 1
  • 2
  • 3
0

In python 3.8 you can do:

class_name = "MyClass"
is_class_in_scope = globals().get(class_name) is not None

Example:

>>> from django.test import TestCase
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'TestCase': <class 'django.test.testcases.TestCase'>}
>>> globals().get('TestCase') is not None
True
Trang Pham
  • 161
  • 1
  • 4