Picking a random class from a file of classes Python

Question:

I have a python file filled with 161 different classes. I am trying to pick one class randomly from the file to be used in the main section of my program. I initially started using Pythons random choosing a number between 1 and 161 then writing out a match pattern to select one corresponding to a number. After completing 4 of these I realised it was going to take hours and could not find an alternative online. Thank you for any help.

For reference, the file with all the classes is named "champions.py" and I only need to take the title for each class. E.g. for the following class I only want to take "aatrox"

class aatrox:
    name = "Aatrox"
    gender = "Male"
    position = ["Top", "Middle"]
    species = ["Darkin"]
    resource = "Manaless"
    rangeType = "Melee"
    region = ["Noxus"]
    releaseYear = 2019
Asked By: Matt

||

Answers:

You can try to put all of your class in a list and then randomly select a class from that list using the random library built into Python.

from champions import *
# so you don't have to write champions.this champions.that
import random # random module
classes = [aatrox, other_class, also_other_class]
chosen_class = random.choice(classes)

chosen_class is going to be a class.

Reference How can I get a list of all classes within current module in Python? for not needing to type all of the class names.

Answered By: The Peeps191

You can get the attribute dictionary of your module by its __dict__ attribute, and then use isinstance to determine whether its value is a class and discard the classes imported from other modules by comparing strings:

import collections

def get_classes(module):
    module_name = module.__name__
    return [v for v in module.__dict__.values() if isinstance(v, type) and v.__module__ == module_name]


print(get_classes(collections))

Output:

[<class 'collections.deque'>, <class 'collections.defaultdict'>, <class 'collections._OrderedDictKeysView'>, <class 'collections._OrderedDictItemsView'>, <class 'collections._OrderedDictValuesView'>, <class 'collections._Link'>, <class 'collections.OrderedDict'>, <class 'collections.Counter'>, <class 'collections.ChainMap'>, <class 'collections.UserDict'>, <class 'collections.UserList'>, <class 'collections.UserString'>]

Then randomly select from the class list:

import random
import your_module   # should be imported before get classes

cls = random.choice(get_classes(your_module))
Answered By: Mechanic Pig

You can examine your champions module to see what names are defined in it. Since there are likely to be some additional names set by the class machinery, you can test to see which ones correspond to classes (instances of type).

import champions

class_names = [name for name, value in champions.__dict__.items()
                    if isinstance(value, type)]
Answered By: Blckknght