Suppose I have a class Foo
, I want to define a function that receives the class constructor as a parameter:
def bar(class_name):
local_class = None
# TODO: if I call bar(Foo()), I want to get local_class = Foo()
How can I implement the function?
The following bar
function will work. Note, the first parameter will be a class itself and not the name of a class, so "class_name
", which implies that it's a str
, is misleading. args
will be a tuple of args to initialize klass
objects with, *-unpacked in the calls to klass
. You said in a later comment that you wanted to "create multiple independent objects", all of the same class and initialized with the same args, so I've revised my answer to reflect that:
def bar(klass, *args):
# Now you can create multiple independent objects of type klass,
# all initialized with the same args
obj1 = klass(*args)
obj2 = klass(*args)
# ...
# do whatever you have in mind with the objs
Your "local_class
" isn't a class at all, but rather an instance of klass
, so that's a bad name; and anyway you want several of them.
Assuming Foo
objects are initialized with three int arguments, and Baz
objects with two strings, you can call bar
like so:
bar(Foo, 1, 2, 3)
bar(Baz, 'Yo', 'bro')
etc.
Especially in a dynamically-typed language like Python, reasoning about code is more difficult when variables have misleading names.
When can pass the classname as an argument to your function, and then call class_name()
. E.g., if you also want to pass arguments.
class Foo:
def __init__(self, arg1, arg2):
pass
def bar1(class_name):
args = ("val1", "val2")
local_class = class_name(*args)
or
def bar2(class_name):
kwargs = {'arg1':'val1','arg2':'val2'}
local_class = class_name(**kwargs)
You can call the functions like:
one = bar1(Foo)
two = bar2(Foo)
If you really want to call the class from a string read this post. I would suggest you use @Evan Fosmark's solution because use of eval
and globals
should be avoided
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With