这两种情况之间有什么区别:传递类名与对象

时间:2019-01-24 17:15:15

标签: python

我是Python的新手,不确定很多习语。我找到了一个函数将类名作为参数的代码。有什么理由吗?我将代码简化为:

class A:
    def __init__(self):
        print ("A")


def foo_1(a):
    inst = a()
    return inst


def foo_2(a):
    inst = a
    return inst


if __name__ == "__main__":
    i1 = foo_1(A)
    i2 = foo_2(A())

像foo_1(现在实现它的方式)那样实现它和foo_2(我认为更直观的方式)之间是否有区别

谢谢!

2 个答案:

答案 0 :(得分:2)

这些功能稍有不同。

foo_1传递了一个class(本身是一个对象),而不仅仅是其名称。然后,实例化该类的实例,并返回该实例。

foo_2传递了一个实例(实际上,在此简化示例中为任何对象),然后将其返回。

在此示例中,这意味着i1i2似乎相同。但是它们实际上是不同的对象,例如,它们不会比较相等。

您将使用foo_1之类的东西作为某些类实例的工厂,或者在创建实例之前修改类对象。如果要对实例执行操作,则可以使用foo_2。特别是,这意味着,如果多次调用该函数,则每次都可以传递相同的实例,而foo_1将始终生成一个新实例。

所以,这取决于您想做什么。

答案 1 :(得分:1)

foo_2的用途可以简化为仅使用对象,这就是您应该做的。

两个选项都可以使用,但是foo_1是一种奇怪的处理方式,除非您没有立即访问要实例化的类的权限。

i = foo_2(A())

相同
i = A()

假设您有一个新的类B,必须使用一些参数对其进行实例化。从foo_1进行调用更加复杂。

class B:
    def __init__(self, c):
        self.c = c

您可以这样做:

i = B()
j = foo_2(B())
k = foo_1(B) => TypeError: __init__() missing 1 required positional argument: 'c'

您可以修改foo_1来获取参数,如果您不知道要实例化哪个类(如果通过用户输入获取该类),这可能会很有用。

# function that takes 1 parameter followed by any number of paramters
def foo_3(klass, *params):
    inst = klass(*params)  # pass the any number of paramters onto the instantiation
    return inst