如何将一个类的构造函数传递给Python函数

10

假设我有一个类Foo,我想定义一个函数,该函数接收类构造函数作为参数:

假设我有一个类Foo,我想定义一个接收类构造函数作为参数的函数:

def bar(class_name):
    local_class = None
    # TODO: if I call bar(Foo()), I want to get local_class = Foo()

我该如何实现这个函数?


3
当你调用bar(Foo())时,你会使用Foo()的实例来调用bar()函数,那么你不能直接使用该实例吗? - Anand S Kumar
@AnandSKumar 在函数内部,我想使用参数“class_name”获取类的多个独立实例。 - beaver
@海狸 bar(functools.partial(Foo, 1, 2, 3)) - Huazuo Gao
@AnandSKumar 我想传递通常生成一个类对象的东西,例如“Foo(1,2,3)”,以便在函数“bar”内部,我可以获取多个独立对象,所有这些对象都应等同于创建为“Foo(1,2,3)”。 - beaver
@HuazuoGao,很抱歉,但是这种方式调用函数有点不太优雅。 - beaver
显示剩余4条评论
2个回答

12

以下的 bar 函数将会生效。需要注意,第一个参数将会是一个 本身而不是类的名称,所以“class_name”这个名字是误导的,因为它暗示了它是一个 strargs 将会是一个元组,包含用来初始化 klass 对象的参数,*解包在调用 klass 的时候完成。你在之后的评论中说你想要“创建多个独立的对象”,所有的这些对象都属于同一个类并且用相同的参数进行初始化,所以我修改了我的答案反映出这一点:

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

你的“local_class”实际上并不是一个类,而是klass的一个实例,所以这是一个不好的命名方式,而且你可能需要多个这样的实例。

假设Foo对象需要用三个int参数进行初始化,而Baz对象需要用两个字符串进行初始化,你可以这样调用bar

bar(Foo, 1, 2, 3)
bar(Baz, 'Yo', 'bro')
特别是在像Python这样的动态类型语言中,当变量名称具有误导性时,对代码进行推理更加困难。

1
当您可以将类名作为参数传递给函数,并调用 class_name() 时。例如,如果您还想传递参数。
class Foo:
    def __init__(self, arg1, arg2):
        pass

def bar1(class_name):
    args = ("val1", "val2")
    local_class = class_name(*args)

或者

def bar2(class_name):
    kwargs = {'arg1':'val1','arg2':'val2'}
    local_class = class_name(**kwargs)

您可以这样调用函数:

one = bar1(Foo)
two = bar2(Foo)

如果您想要从一个字符串中调用类,请阅读this文章。我建议您使用@Evan Fosmark的解决方案,因为应该避免使用eval和globals。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接