这个算法的 pythonic 方法是什么?

What's the pythonic method for this algorithm?

我有一个 class,我希望能够像这样使用它:

obj = MyClass(arg1, arg2)
if (obj is None):
    # tell user to try again
else:
    # give user options for continuing

对象创建的基本算法(在__init__and/or__new__,我不确定)应该是这样的:

retrieve database record from arg1 and arg2 search criteria
if a record is returned
    setup instance variables
else
    return None

是否有明确的 pythonic 方式来做到这一点?我读过一些建议改为引发异常的文章,但这似乎不正确,因为这是预期的行为。我看到其他人建议使用 __new__,但是我如何在不检查 __init__ 来设置实例变量的情况下检查 __new__ 中的数据库以查看记录是否有效?

Pythonic 的做法是不要这样做。做MyClass(whatever)就是实例化一个对象;根据定义,这将始终创建一个实例。

一种替代方法可能是将工厂函数定义为类方法,它可以是 return 对象也可以不是对象。

class MyClass(object):
    ...

    @classmethod
    def create_maybe(cls, arg1, arg2):
        ... do logic ...
        if whatever:
            return cls(arg1, arg2)

现在要创建您的对象,您可以调用 MyClass.create_maybe(arg1, arg2)

我认为最好的方法是在 class 之上创建一个工厂,如果 class 无法检索正确的数据库记录,则让其引发异常,即:

class MyClass:
    def __init__(self, arg1, arg2):
        if arg1 or arg2:
            raise Exception()


def my_class(arg1, arg2):
    try:
        return MyClass(arg1, arg2)
    except Exception:  # using the default exception for simplicity
        return None


obj = my_class(arg1, arg2)
if obj is None:
    pass  # try again
else:
    pass  # other options

请不要在上面的代码中使用默认的 Exception class,而是为您的模块的特定 class 创建一个异常,或者使用内置异常之一。

在这里提出异常是完全有效的。 SQLAlchemy,一个比较流行的Python ORM,提出了一个NoResultFound exception if a record was needed but couldn't be found (although this is from a function, not a class instantiation, so perhaps not directly comparable). I don't think it would be unusual at all to do this—it's not bad form to raise exceptions in __init__!

你想表达的"an absence of a value, but not an error"的想法类似于Option type, but this isn't really a Pythonic construct. As stated in 'Is there a Python equivalent for Scala's Option or Either?',Pythonic方式抛出一个异常。

您不应将异常视为意味着您的程序已损坏,只是在某种程度上中断了预期的事件流。您可能喜欢阅读“When and how should I use exceptions?”,它给出了一些关于 Python.

中异常的常见哲学的想法

作为, it's Easier to Ask for Forgiveness than Permission:

This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.

您应该假设记录存在,如果不存在则处理错误。 Python 就是围绕这个设计的,如果您遵循 EAFP,您会发现代码最终会变得更清晰。