0

I have searched high and low and can't find a proper solution.

I need to dynamically create objects and store them in dictionaries using a for loop from a class that is in a different file.

To avoid name space pollution I like to import my modules like so:

from my_folder import my_file as mf

the loop looks like this:

self.my_dict = {} # create empty dictionary

    for F in ('One', 'Two', 'Three', ...):
        object = F(var1, var2)
        self.my_dict[F] = object

on the line object = F(var1, var2) I need the F be referring to mf.One, mf.Two and so on.

How do I append the value F to mf so it reads it as mf.value-of-F instead of reading it as mf.F?

I know I must be missing something very obvious, just not obvious to me right now. Thanks

Iguananaut
  • 21,810
  • 5
  • 50
  • 63
Ernie Peters
  • 537
  • 1
  • 6
  • 18
  • you can call `getattr(mf, F)(var1, var2)` – PRMoureu Oct 21 '17 at 14:04
  • 2
    Possible duplicate of [Calling a function of a module from a string with the function's name](https://stackoverflow.com/questions/3061/calling-a-function-of-a-module-from-a-string-with-the-functions-name) What you're looking for is `getattr`. – Iguananaut Oct 21 '17 at 14:05
  • BTW, you shouldn't use `object` as a variable name because that shadows the built-in `object` type. – PM 2Ring Oct 21 '17 at 14:07
  • 2
    Why not just use `for F in (mf.One, mf.Two, mf.Three)`? – Bryan Oakley Oct 21 '17 at 14:09
  • What PRMoureu said should work, but there's probably a better way to organize your code. Eg, put the functions in the `mf` into a dict, with their names as the keys. Or just do it like Bryan Oakley suggests. – PM 2Ring Oct 21 '17 at 14:10
  • I did see the examples using `getattr` but they were using it to import a module from a class in a different file. Due to my newbieness, I want sure it applied to my scenario but could have tried I guess. – Ernie Peters Oct 21 '17 at 23:42
  • @Iguananaut. I did realize my question was almost identical to an existing one. I did have a look at it. I was just not happy with the solution given. – Ernie Peters Oct 21 '17 at 23:49
  • @PM 2Ring. I never use object as a variable in my actual code however, I did in my question to point out the obvious. Thanks though;) – Ernie Peters Oct 21 '17 at 23:51
  • Understood. It's quite common for people to do stuff like that with list, str, dict, set, etc when explaining algorithms. But I don't think it's a good idea, since it often leads to conversations like this, and it could confuse innocent bystanders. ;) And of course, it's pretty rare that people need to use the `object` type explicitly in Python 3 code, but still... – PM 2Ring Oct 22 '17 at 06:11

2 Answers2

1

Try to use such syntax:

object = mf.__dict__[F](var1, var2)
Valner
  • 36
  • 2
  • 1
    Although this is necessary in some cases, it can be problematic, for example, if the object you're accessing is a descriptor. This generally only makes sense if you have some reason to bypass the descriptor protocol, `__getattribute__`, etc. (which sometimes you do). – Iguananaut Oct 22 '17 at 14:54
1

There are almost certainly better solutions to your problem, but your example is so short and contrived that it's hard to give good advice.

To address the specific question you asked, you can use getattr to get a function or class from a module based on a string:

for F in ('One', 'Two', 'Three', ...):
    Cls = getattr(mf, F)
    obj = Cls(var1, var2)
    self.my_dict[F] = obj

A simpler approach might be to iterate over the classes themselves:

for F in (mf.One, mf.Two, mf.Three):
    obj = F(var1, var2)
    ...
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thanks Bryan. As always, simple, direct answers without wanting to be complicated. I knew I was over thinking this rather simple task. – Ernie Peters Oct 21 '17 at 23:46