Referring to class names through strings?

I need to parse a text file, create objects for various objects found in the text, and put them in some data structure (for example, a list) for further processing. Sample text:

laptop 17" dell, weight: 12 lb desktop 24" hp 

I know in advance what objects can exist in the text and what attributes they should have. In this example, I already had classes designed for laptops and desktop computers (possibly subclasses of the computer class). The parser would just need to create the objects laptop ('dell', 17, 12) and dekstop ('hp', 24).

If I follow this route, I will need to get class names from strings and create objects of these classes. Is this a pythonic way of doing things? If so, what is the best approach (using Python 3.1)? If not, what should I do instead?

Thanks!

what

+1
source share
5 answers

If classes are defined in computers.py , let's say you can do

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

to create an instance of a computers.Laptop . If they are defined in the same file in which you use the code (so these are global variables), you can do

 globals()[ "Laptop" ] 

but it is less elegant; it would be better to place them in a separate area.

Alternatively, if you want a more powerful collation (let's say you want Netpop, Lapbook, and Laptop to all create a Laptop instance), you could support string matching with the appropriate constructor and use this

 mapping = { "Laptop": Laptop, "Nettop": Laptop, ... } mapping[ "Laptop" ]() 
+11
source

you can create instances of a class by its name using the following code

 obj = globals()[classname]() 

where classname is a string

+5
source

Technically, what you're asking for (or at least the way everyone interprets it) is not a good practice, especially if you can take input from an unreliable source (remember that any source other than you should generally considered unreliable!). You must clearly state these things explicitly, because someone can initiate a function or create an object that you did not intend, with properties that you really do not need ...

Instead, you can do something like this (this, of course, is wildly incomplete, but should give you a 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 a mapping for each new type of object in the dict_classes dict.

+4
source

I think that a verification-based method could potentially be quite fragile and resilient to change. What if you want to use classes from other modules?

Why not a factory object? It can be a simple function or 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) 
+1
source

Not sure about python code syntax, but is that 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
source

All Articles