Python __init__ 返回创建失败
Posted
技术标签:
【中文标题】Python __init__ 返回创建失败【英文标题】:Python __init__ return failure to create 【发布时间】:2013-06-24 08:25:46 【问题描述】:首先,我知道 Python 中类的 __init__()
函数不能返回值,所以很遗憾这个选项不可用。
由于我的代码结构,在类的__init__
函数中包含数据断言(并提示用户提供信息)是有意义的。但是,这意味着对象的创建可能会失败,我希望能够优雅地从中恢复。
我想知道继续进行此操作的最佳方法是什么。我考虑过将全局布尔值设置为“有效构造”标志,但我不希望这样做。
还有其他想法吗(除了重组,因此断言可以在初始化之外发生并且值作为参数传入)?我基本上是在寻找一种在初始化期间成功返回 0 并在失败时返回 -1 的方法。 (和大多数 C 系统调用一样)
【问题讨论】:
引发异常。 成功返回 0 失败返回 -1 是非常不符合 Python 的。错误返回是不好的,因为它们很容易被忽略,而且处理起来很冗长。最重要的是,使用 0 和 -1 作为布尔值只会增加混乱而没有任何好处。不要真正使用 Python 编写 C 代码。 正如@jsbueno 在他的回答中指出的那样,类实例在__init__()
中初始化,而不是创建,这就是为什么它没有return
一个值。您可以在类中添加一个数据成员以指示其状态,然后直接检查其值或调用在调用 __init__()
后返回其值的方法,而不是使用全局变量来检测失败或抛出异常确定错误时是否有任何(以及可能是什么)。
【参考方案1】:
您可以在 assertio 失败时引发异常,或者 - 如果您真的不希望或不能处理异常,您可以在类中编写 __new__
方法 -
在 Python 中,__init__
在技术上是一种“初始化器”方法——它应该填写属性并获取对象在其生命周期中需要的一些资源和其他资源——但是,Python 确实定义了一个真正的构造函数,@987654323 @ 方法,在 __init__
- 之前调用,与此不同的是,__new__
实际上确实返回一个值:新创建的(未初始化的)实例本身。
因此,您可以将检查放在 __new__
中,然后简单地返回 None 是失败 - 否则,将调用结果返回到超类 __new__
方法(无法为对象执行实际的内存分配在纯 Python 中,因此最终您必须在超类中调用用本机代码编写的构造函数 - 通常这是类层次结构基础中的 object.__new__
。
注意:在 Python 2 中,您必须将 object
作为层次结构的基类 - 否则不仅不会调用 __new__
,因为后来添加了很多功能到 Python对象将无法正常工作。简而言之,class MyClass(object):
,永远不要class MyClass:
——除非你在 Python3 上。
【讨论】:
你说__new__
在__init__
之前被调用。我刚试过这个,但是当我创建一个类的实例(Py2.7)时,__new__
没有被调用。
我找到了。你需要在你的类中扩展对象。没有它, new 将不会被调用!
没有。如果我省略对象基类,__new__
不会自动调用。去图吧!
不,又不。除非我添加对象基类,否则不会调用我的打印。
呵呵。不仅我陷入了陷阱;-) 你会在你的答案中添加一个注释,以便我们可以删除这个讨论吗?【参考方案2】:
您是否考虑过引发异常?这是发出失败信号的常用方式。
【讨论】:
以上是关于Python __init__ 返回创建失败的主要内容,如果未能解决你的问题,请参考以下文章
为啥允许在 Python 中使用 super 从 __init__ 返回一个值?