在python中,实现构造函数可能失败的类的正确方法是什么?

时间:2022-12-05 14:30:19

For example, in the constructor I need to grab some resources which could fail, in that case the class shouldn't be instantiated.

例如,在构造函数中,我需要获取一些可能失败的资源,在这种情况下,类不应该被实例化。

Should I throw exception in the constructor?

我应该在构造函数中抛出异常吗?

class Foo(object):
    def __init__(self):
        self.rsc = get_resource():
        assert self.rsc

And try to catch it in the instantiation code?

试着在实例化代码中捕获它?

try:
    a = Foo()
except:
    a = None

Then later code checks if a is None.

然后,代码检查a是否为None。

2 个解决方案

#1


3  

Expanding my earlier comment into an answer:

把我先前的评论扩展成一个答案:

It's better to add the resource as a constructor parameter, like this:

最好将资源添加为构造函数参数,如下所示:

class Foo(object):
    def __init__(self, rsc):
        self.rsc = rsc

This approach has a number of benefits:

这种方法有很多好处:

  • The constructor can no longer fail
  • 构造函数不能再失败。
  • You no longer have an expensive constructor
  • 您不再拥有一个昂贵的构造函数。
  • You have looser coupling between Foo and its resource type
  • 在Foo和它的资源类型之间有更松散的耦合。

And if you like the interface of implicitly acquiring a resource, it is easy to wrap this. A simple function like make_foo attempts to acquire the resource automatically, returning None (or raising an error, if you prefer) when it cannot:

如果您喜欢隐式获取资源的接口,那么很容易将其包装起来。像make_foo这样的简单函数试图自动获取资源,如果不能,则返回None(或引发错误):

def make_foo():
    rsc = get_resource()
    if rsc:
        return Foo(rsc)
    else:
        return None

#2


-3  

Not really a problem, just add try...except in the init function and have it assign a specific value like None in case of failure, or add additional features

不是真的有问题,只是增加尝试……除了在init函数中,并在失败时指定一个特定的值,或者添加其他特性。

class Foo(object):
    def __init__(self):
        try:
            self.rsc = get_resource()
            self.success = True
        except:
            self.rsc = None
            self.success = False

a = Foo()
if a.success:
    print(a.rsc)
else:
    do_something_else()

#1


3  

Expanding my earlier comment into an answer:

把我先前的评论扩展成一个答案:

It's better to add the resource as a constructor parameter, like this:

最好将资源添加为构造函数参数,如下所示:

class Foo(object):
    def __init__(self, rsc):
        self.rsc = rsc

This approach has a number of benefits:

这种方法有很多好处:

  • The constructor can no longer fail
  • 构造函数不能再失败。
  • You no longer have an expensive constructor
  • 您不再拥有一个昂贵的构造函数。
  • You have looser coupling between Foo and its resource type
  • 在Foo和它的资源类型之间有更松散的耦合。

And if you like the interface of implicitly acquiring a resource, it is easy to wrap this. A simple function like make_foo attempts to acquire the resource automatically, returning None (or raising an error, if you prefer) when it cannot:

如果您喜欢隐式获取资源的接口,那么很容易将其包装起来。像make_foo这样的简单函数试图自动获取资源,如果不能,则返回None(或引发错误):

def make_foo():
    rsc = get_resource()
    if rsc:
        return Foo(rsc)
    else:
        return None

#2


-3  

Not really a problem, just add try...except in the init function and have it assign a specific value like None in case of failure, or add additional features

不是真的有问题,只是增加尝试……除了在init函数中,并在失败时指定一个特定的值,或者添加其他特性。

class Foo(object):
    def __init__(self):
        try:
            self.rsc = get_resource()
            self.success = True
        except:
            self.rsc = None
            self.success = False

a = Foo()
if a.success:
    print(a.rsc)
else:
    do_something_else()