2010-09-17 77 views
0

如果要打印一堆Python中的變量,你有好幾個選擇,如:Python中的raise對象在哪裏?

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

OR

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

我之所以用它代替sys.stdout.write函數在第二個例子中打印的是lambda表達式不會接受打印,但是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中有沒有這樣的提升對象,如果有,它在哪裏?

+1

-1:哇,這一切都很糟糕。請不要玩這樣的代碼高爾夫球。請不要讓Python無法讀取。第一種風格有什麼問題?這是有道理的。爲什麼使用讓事物變得模糊的奇怪的地圖技術?這些默默無聞的重點是什麼?它不會更快。閱讀起來並不容易。爲什麼要這樣做? – 2010-09-17 10:05:14

+0

@S。洛特前兩個地圖的例子是無用的,但他們只是演示sys.stoud.write和我想用raise的方式。但是我不明白爲什麼第三張地圖可能會壞。 – cory 2010-09-17 15:53:34

+0

爲什麼在使用'from __future__ import print_function'時使用'sys.stdout.write'? – 2010-09-17 17:28:58

回答

4

沒有Python的「對象」(內置或標準庫)爲raise,你必須建立一個自己(典型的短片斷進去一個人的util.py ...!):

def do_raise(exc): raise exc 

通常被稱爲do_raise(InvalidObjectError(o.name))

+0

我對名字'do_raise'感到c 0123' – Gabe 2010-09-17 03:56:58

+2

使用Python關鍵詞作爲標識符的傳統方法是'raise_'。 – 2010-09-17 04:14:19

+0

@加貝:或許你應該對這個被接受的答案感到不安。 – 2010-09-17 10:22:03

2

我不認爲有可能在lambda中使用raise,就像您正在嘗試的那樣。 raise是一個語句/表達式,而不是一個對象。正如@Alex Martelli所說的,您可能需要定義一個函數來爲您進行檢查。現在,該函數可以在同一個上下文中進行本地聲明。

至於異常類型,這是你的問題似乎針對:異常類型不會自動定義。對於簡單的異常類型,你要麼需要只是一個文本消息,或者根本沒有,典型的異常類型是在你的模塊/文件範圍爲簡單的定義:

class InvalidObjectError(Exception): pass 
+0

其實你的回答的第一部分是正確的,我確實想知道是否有一個用於加載語句的對象,就像打印語句的對象一樣。 – cory 2010-09-17 03:00:58

+0

「我不認爲有可能在lambda中使用raise,就像你試圖做的那樣。raise是一個語句/表達式,而不是一個對象。」有人可能會說這意味着python的功能不夠。 – g33kz0r 2012-05-14 04:11:03

0

對於你的第一個例子中,我使用的形式是這樣的:

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 

忽略不存在的一系列步驟參數,因爲我認爲功能是其他更復雜的功能簡化。

1

Do.不。做。這個。

這是一個可怕的想法。

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 ] 

沒有地圖。沒有拉姆達。同樣的行爲。

+0

地圖和lambda有什麼問題?在我看來,你還會推薦使用for循環和if語句來代替filter(),它只能用於(在我的眼中)繪製過程。 – cory 2010-09-17 19:22:09

+0

@cory:過濾器很難與此相媲美。使用'lambda'試圖引發異常太複雜。沒有評論過濾。只評論你的確切用例。這裏的實際驗證非常簡單得多。沒有地圖。沒有Lambda。 '[x.validate()for x in iterable]''。如果有任何對象無效,則會引發異常。完成。沒有地圖。沒有Lambda。 – 2010-09-17 19:58:53