【问题标题】:Where is the raise object in Python?Python 中的 raise 对象在哪里?
【发布时间】:2010-09-17 02:44:31
【问题描述】:

当你想在 Python 中打印一堆变量时,你有很多选择,例如:

for i in range(len(iterable)):
    print iterable[i].name

map(lambda i: sys.stdout.write(i.name), iterable)

我在第二个示例中使用 sys.stdout.write 而不是 print 的原因是 lambdas 不接受打印,但 sys.stdout.write 具有相同的目的。

您还可以使用三元运算符有条件地打印:

map(lambda n: None if n % 2 else sys.stdout.write(str(n)), range(1, 100))

因此,如果我可以检查整个序列中是否存在可以保证异常的条件,那将非常方便:

map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)

但这不起作用。 Python中是否有raise这样的对象,如果有,在哪里?

【问题讨论】:

  • -1:哇,这太糟糕了。请不要那样打代码高尔夫。请不要让 Python 不可读。第一种风格有什么问题?这是有道理的。为什么要使用使事情变得模糊的奇异地图技术?所有这些默默无闻的意义何在?它不会更快。它不会更容易阅读。为什么要这样做?
  • @S. Lott 的前两个地图示例毫无用处,但它们只是为了演示 sys.stoud.write 以及我想使用 raise 的方式。但如果可能的话,我不明白为什么第三张地图会很糟糕。
  • 既然可以使用from __future__ import print_function,为什么还要使用sys.stdout.write
  • 也是不错的选择。太糟糕了,未来还没有 raise_function。

标签: python raise


【解决方案1】:

raise 没有 Python“对象”(内置或在标准库中),您必须自己构建一个(典型的短 sn-p 包含在一个 util.py...!):

def do_raise(exc): raise exc

通常被称为do_raise(InvalidObjectError(o.name))

【讨论】:

  • 我对@9​​87654325@这个名字感到畏缩
  • 使用 Python 关键字作为标识符的常规方法是 raise_
  • @Gabe:也许你应该对这是公认答案的情况感到畏缩。
【解决方案2】:

我认为在 lambda 中使用 raise 是不可能的,就像您尝试做的那样。 raise 是一个语句/表达式,而不是一个对象。正如@Alex Martelli 所说,您可能需要定义一个函数来为您进行检查。现在,函数可以在本地声明,在相同的上下文中。

就异常类型而言,您的问题似乎是针对的:异常类型不是自动定义的。对于简单的异常类型,您要么只需要一条文本消息,要么根本不需要,通常异常类型仅在您的模块/文件范围内定义为:

class InvalidObjectError(Exception): pass

【讨论】:

  • 其实你回答的第一部分是对的,我确实想知道 raise 语句是否有一个对象,就像 print 语句一样。
  • “我认为不可能在 lambda 中使用 raise,就像您尝试做的那样。raise 是一个语句/表达式,而不是一个对象。”有人可能会说这意味着 python只是功能不够。
【解决方案3】:

做。不是。做。这个。

这是一个可怕的想法。

map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)

这样做。

class SomeValidatingClass( object ):
    def isValid( self ):
        try: 
            self.validate()
        except InvalidObjectError:
            return False
        return True
    def validate( self ):
        """raises InvalidObjectErorr if there's a problem."""

[ x.validate() for x in iterable ]

没有地图。没有拉姆达。同样的行为。

【讨论】:

  • map 和 lambda 有什么问题?在我看来,您还建议使用 for 循环和 if 语句而不是 filter(),它仅用于(在我看来)绘制流程。
  • @cory:过滤器很难与此相提并论。使用lambda 来尝试引发异常太复杂了。不评论过滤。仅评论您的确切用例。实际的验证在这里要简单得多。没有地图。没有拉姆达。 [ x.validate() for x in iterable ]。如果任何对象无效,您就会引发异常。完毕。没有地图。没有 Lambda。
【解决方案4】:

对于您的第一个示例,我使用如下形式:

print '\n'.join(obj.name for obj in iterable)

我也会使用:

firstnotvalid = next(obj.name for obj in iterable if not obj.is_valid())

而不是:

>>> import sys
>>> map(lambda n: None if n % 2 else sys.stdout.write(str(n)), range(1, 100))
2468101214161820222426283032343638404244464850525456586062646668707274767880828486889092949698[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]

我愿意:

>>> print (', '.join(str(number) for number in range(1,100) if not number % 2))
2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98

忽略范围有step参数,因为我认为该功能是其他更复杂功能的简化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    相关资源
    最近更新 更多