简体   繁体   中英

Python: how to assign a name of a list variable to a class

Basically, I have a list of lists that looks like this:

lst = [['B', 'A'], ['C', 'B'], ['D', 'B'], ['E','C D'] ......]

Where t[0] supposed to be a subclass of t[1] (from which it inherits).

I need to write a script that creates empty classes with names matching lst and then checks whenever a t[i-1] is a subclass of t[i] :

if issubclass(B, A)== True:
   print('Yes')
   

So far, I understand how to begin and how to finish the script but I'm completely unaware how to assign a name from a list so that it would be possible to use issubclass . Maybe there are other ways of creating classes and tracing their inheritance?

I've just started learning classes and OOP today, so it's more than possible that I missed something crucial while dealing with this problem.

The usual way we define classes is with the class keyword, naturally.

class B(A):
    some_variable = 100

Effectively, we're constructing a new type in the Python runtime. And, in fact, types have their own constructor in Python; it's called type and we can call it directly. The above declaration is roughly equivalent to

B = type('B', ('A',), { 'some_variable': 100 })

And now the type names are strings. There's just one more piece of the puzzle we'll need. We want to take and assign it to the name B , using a string so we can do so with names that aren't known in advance. Assuming you want to do this at module-scope, we can use globals , which returns a dictionary of the current module's top-level variables, which we can freely modify to add more variables. So we can do

globals()['B'] = type('B', ('A',), { 'some_variable': 100 })

Now, let's put those pieces together and write a script that uses the lst list you suggested.

lst = [['B', 'A'], ['C', 'B'], ['D', 'B'], ['E','C D']]

# Iterate over the list.
for class_name, superclass_names in lst:
    # Here, we're going to lookup all of the superclass names in the
    # current global scope. It's a little more complicated than that,
    # since we also want to *create* any names that don't exist (like
    # 'A' in your example) when we find them.
    superclasses = []
    for superclass_name in superclass_names.split(' '):
        # If the name doesn't exist, create it and assume its
        # supertype is object, the root of Python's type hierarchy.
        if superclass_name not in globals():
            globals()[superclass_name] = type(superclass_name, (object,), {})
        # Get the class, whether it's the one we just made or one that
        # already exists.
        superclasses.append(globals()[superclass_name])
    # Now we construct the new class. The first argument to type() is
    # the class name, the second is all of the superclasses (it must
    # be a tuple, not a list, according to the documentation, so we
    # convert it), and finally the contents. Since you just want the
    # classes themselves, I'll assume the contents are meant to be
    # empty. You can easily change that as needed.
    globals()[class_name] = type(class_name, tuple(superclasses), {})

# Now let's see that everything is defined correctly. __mro__ is a
# complicated concept, but the basic idea is that it should give us E,
# followed by all of its subclasses in a reasonable order (for some
# definition of reasonable).
print(E.__mro__)

Try it online!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM