4

I know a similar question has been asked/answered several times. But please do read on ..

I am trying to create a Class from a string value as described in "Convert string to Python Class Object" in Python 3.6.

utils.py

class Foo(object):
    def __init__(self):
        print("In the constructor of Foo")

    def What(self):
        print("so what ... ")

class FooParam(object):
    def __init__(self, v):
        self.value = v
        print("In the constructor of FooParam")

    def What(self):
        print("Value=" % self.value)
        print("So what now ...")

welcome.py

def TEST1():
    m = importlib.import_module("utils")
    c = getattr(m, "Foo")
    c.What()  

if __name__ == '__main__': 
    TEST1()

Error

TypeError: What() missing 1 required positional argument: 'self'

So what am I doing wrong ?

Also how can I create an object of "FooParam" and pass a value to the constructor.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
lightsunray
  • 409
  • 5
  • 16
  • _"how can I create an object of "FooParam" and pass a value to the constructor."_ -> You call its constructor with an argument. `FooParam = getattr(m, "FooParam"); obj = FooParam(whatever)`. – Aran-Fey Mar 22 '18 at 16:55

2 Answers2

2

Once you import the module just access with the variable you stored imported module:

m = importlib.import_module("utils")
foo = m.Foo()
foo.What()

import_module performs the same steps as import.

This c = getattr(m, "Foo") line of code is equivalent f = Foo so that means you are not creating an instance instead you are getting a reference to that class.

metmirr
  • 4,234
  • 2
  • 21
  • 34
  • Thank you both for the answer. It is embarrasing to have missed an important point of the importlib. It works now. – lightsunray Mar 22 '18 at 17:25
1

I suspect that c is the class Foo but not an instance of the class.

This is equivalent to simply calling

Foo.what()

Which is why self is not defined!

Whereas what you want is to create an instance of the class (giving it a 'self' property), then call its method, i.e.

foo_instance = Foo()
foo_instance.What()

so try replacing c.What() with..

foo_instance = c()
foo_instance.What()

for FooParam:

#import the class FooParam
c = getattr(m, "FooParam")
#create an instance of the class, initializing its values (and self)
fooparam_instance = c(3.14)
#call its method!
fooparam_instance.What()

on the whole I would rename the variable c, to something like foo_import and fooparam_import respectively :)

RandomBob
  • 106
  • 1