Referring to class names through strings?

后端 未结 5 1062
面向向阳花
面向向阳花 2021-01-16 17:32

I need to parse some text file, create objects for various entities encountered in the text, and put them in some data structure (e.g., a list) for further processing. Examp

相关标签:
5条回答
  • 2021-01-16 18:11

    you can create instances of a class by it's name using the following code

    obj = globals()[classname]()
    

    where classname is a string

    0 讨论(0)
  • 2021-01-16 18:13

    If the classes are defined in computers.py, say, you can do

    import computers
    getattr( computers, "Laptop" )( <params> )
    

    to instantiate a computers.Laptop. If they are defined in the same file that you are running the code in (so that they are global variables), you can do

    globals()[ "Laptop" ]
    

    but this is less elegant; it would be nicer to put them in a separate scope.

    Alternatively, if you want a more powerful mapping (say you want "Nettop", "Lapbook", and "Laptop" all to instantiate Laptop), you could maintain a mapping of strings to their corresponding constructor and use that:

    mapping = { "Laptop": Laptop, "Nettop": Laptop, ... }
    mapping[ "Laptop" ]()
    
    0 讨论(0)
  • 2021-01-16 18:13

    Not sure about the syntax of python code but is this what you want?

    for item in parsedString:
        if item == "laptop":
            laptops.add(laptop()) #laptops is a list of laptops you 
                                  #have encountered so far in your list
        # add the next elements to your laptop instance
    
        if item == "desktop":
        # code for desktop...
    
    0 讨论(0)
  • 2021-01-16 18:19

    I think a inspection-based method would potentially be quite fragile and resistant to change. What if you want to use classes from other modules?

    Why not a object factory? It could be a simple function or a class.

    Example:

    class ComputerFactory:
    
       def __init__(self):
          self._classes = {}
    
       def register(moniker, creator):
          """Moniker is a name for the class.
          Creator is a callable that creates the object 
          for the moniker.
          """
          self._classes[moniker] = creator
    
       def create(moniker, *args, **kwargs):
          return self._classes[moniker](*args, **kwargs)
    
    # Example usage
    fac = ComputerFactory()
    # Register constructor
    fac.register("laptop", Laptop) # Laptop class is also a callable (the constructor)
    # Register construction proxy
    def sony_laptop_builder(make):
       return Laptop("Sony")
    fac.register("laptop", sony_laptop_builder)
    
    0 讨论(0)
  • 2021-01-16 18:20

    Technically, what you're asking for (or at least the way everyone is interpreting it) just isn't very good practice, especially if you might be taking input from an untrusted source (remember, any source other than yourself should generally be considered untrusted!). You should whitelist these things explicitly, because someone might trigger the execution of a function or creation of an object you didn't intend with properties you really don't want...

    What you can do instead is something like this (this is of course wildly incomplete, but should give you the general idea):

    class Laptop(object):
        pass
    class Desktop(object):
        pass
    
    possible_classes = {
        "laptop": Laptop,
        "desktop": Desktop,
    }
    
    new_object = possible_classes[identifier_string](propA, propB, propC, ...)
    

    Then just add the mapping for each new kind of object to the possible_classes dict.

    0 讨论(0)
提交回复
热议问题