2009-10-09 18 views
2

我對Python還很陌生,所以我試圖找出如何做到這一點並需要一些幫助。在不破壞可讀性的情況下對這條Python語句進行壓縮

我使用返回碼來驗證我的內部函數成功返回。例如(內部庫函數):

result = some_function(arg1,arg2) 
if result != OK: return result 

或(從主腳本級別):

result = some_function(arg1,arg2) 
if result != OK: abort_on_error("Could not complete 'some_function': %s" % messages(result)) 

我能得到這個下降到一行沒有使它不可讀?

編輯:有人認識到異常可能是更好的選擇。我只想保存例外情況,僅用於非常「特殊」的情景捕獲。預計返回代碼有時會失敗,我認爲在這種情況下使用例外情況通常是不好的做法。

+2

似乎很濃縮了我。實際上太多了,我認爲錯誤放棄應該放在它自己的路線上。 – 2009-10-09 15:14:00

+0

夠公平的。如果陳述'pythonic'是單線嗎?通常這種語言會讓你使用'pythonic'語法,但它確實可以使用這種語法。 – cgyDeveloper 2009-10-09 15:33:23

+0

單行'if'語句不鼓勵,請參閱Python風格指南,PEP8 http://www.python.org/dev/peps/pep-0008/ – dbr 2009-10-09 16:33:12

回答

3

聽起來好像你想要的東西像..

if result = some_function(arg1, arg2): 
    return result 

這在Python中是非常故意不可能的。編寫if a = b而不是if a == b的錯字太常見了,並且允許將這種分配與流量控制混合在一起。如果這是必要的,它分成兩行:

x = some_function() 
if x: 
    print "Function returned True" 

這方面的一個更實際的例子是..

result = re.match("a", "b") 
if result: 
    print result.groups() 

(更正確,你應該在這種情況下做if result is not None:,雖然上述作品)

在您的具體情況(「驗證我的內部函數成功返回」),這聽起來像你應該使用異常。如果一切都很好,只要返回你想要的東西。如果事情變得糟糕,請舉例說明。

異常在Python並不像很多其他語言 - 例如,他們在內部使用流控制(如StopIteration除外)

我會考慮以下更Python比使用的返回碼:

#!/usr/bin/env python2.6 
def some_function(arg1, arg2): 
    if arg1 + arg2 > 5: 
     return "some data for you" 
    else: 
     raise ValueError("Could not complete, arg1+arg2 was too small") 

然後,你可以調用函數在單行:

return some_function(3, 2) 

這要麼返回值,或將引發異常,這你可以處理這個異常敏感的地方:

def main(): 
    try: 
     result = some_function(3, 5) 
    except ValueError, errormsg: 
     print errormsg 
     sys.exit(1) 
    else: 
     print "Everything is perfect, the result was {0}".format(result) 

或者,如果這種情況下,實際上是一個錯誤,乾脆讓停止一個不錯的堆棧跟蹤的應用程序。

是的,它比一行更長,但Python背後的想法是簡潔,但明確和可讀性。

基本上,如果函數不能再繼續,引發異常。處理這個異常要麼在那裏你可以從問題中恢復,或者用一個錯誤信息呈現給用戶.. 除非你正在寫一個庫,在這種情況下離開異常堆棧運行到調用代碼

或者,在詩的形式:

$ python -m this 
The Zen of Python, by Tim Peters 

Beautiful is better than ugly. 
Explicit is better than implicit. 
Simple is better than complex. 
Complex is better than complicated. 
Flat is better than nested. 
Sparse is better than dense. 
Readability counts. 
Special cases aren't special enough to break the rules. 
Although practicality beats purity. 
Errors should never pass silently. 
Unless explicitly silenced. 
In the face of ambiguity, refuse the temptation to guess. 
There should be one-- and preferably only one --obvious way to do it. 
Although that way may not be obvious at first unless you're Dutch. 
Now is better than never. 
Although never is often better than *right* now. 
If the implementation is hard to explain, it's a bad idea. 
If the implementation is easy to explain, it may be a good idea. 
Namespaces are one honking great idea -- let's do more of those!

最後,它可能是值得一讀了"PEP 8",風格指南爲Python。它可能會回答你的一些問題,比如「如果陳述'pythonic'是單線嗎?」

複合語句(同一行上的多個語句)通常是不鼓勵的。

是:

if foo == 'blah': 
    do_blah_thing() 
do_one() 
do_two() 
do_three() 

而不是:

if foo == 'blah': do_blah_thing() 
do_one(); do_two(); do_three() 
+0

正確的,當我發現您寫的第一個聲明是不可能的時,我來到這裏尋求建議。我想這只是不存在。不過,我會根據這麼多建議來回顧我的代碼/例外邏輯。 – cgyDeveloper 2009-10-09 16:26:38

10

您可以使用異常來指示失敗,而不是返回代碼?然後你的大部分陳述都會消失。

+6

我同意。返回代碼不是非常「pythonic」,或者被認爲是我能想到的任何現代語言的良好實踐。 – 2009-10-09 15:05:28

+0

我想爲「例外」情況保存例外情況。這些函數可能會返回這些代碼。我一直認爲,除了捕捉特殊場景之外,其他任何事情都不例外。 – cgyDeveloper 2009-10-09 15:23:15

+0

那麼這不就是創建一系列try/except塊嗎?還是有一些優雅的處理語法我不知道。 – cgyDeveloper 2009-10-09 15:24:00

3

pythonic

其密切關注Python語言的最常見的成語,而不是使用常見的其他語言的概念,實現代碼的想法或一段代碼[...]

並不意味着寫在線上!

+0

也許這裏沒有很好的語法。我想看看那些對這門語言更熟悉的人會得到什麼。 – cgyDeveloper 2009-10-09 15:27:26

+1

爲此,您需要提供一些實際的代碼 – SilentGhost 2009-10-09 15:27:59

1

如果你堅持不使用例外,那麼我會寫兩行(一個行會太長這裏):

res = some_function(arg1, arg2) 
return res if res != OK else ... 

順便說一句,我建議你拿出一些靜態函數返回值的類型(儘管在Python中進行了動態類型化)。例如,您可能會返回「intNone」。您可以將這樣的描述放入文檔字符串中。

如果你有int結果值和int錯誤代碼你可以通過引入一個錯誤類區分它們:

class ErrorCode(int): pass 

,然後如果結果的ErrorCodeisinstance檢查。

-1

除例外情況,使用裝飾則很好地解決了這個問題:

# Create a function that creates a decorator given a value to fail on... 
def fail_unless(ok_val): 
    def _fail_unless(f): 
     def g(*args, **kwargs): 
      val = f(*args, **kwargs) 
      if val != ok_val: 
       print 'CALLING abort_on_error...' 
      else: 
       return val 
     return g 
    return _fail_unless 


# Now you can use the decorator on any function you'd like to fail 
@fail_unless('OK') 
def no_negatives(n): 
    if n < 0: 
     return 'UH OH!' 
    else: 
     return 'OK' 

在實踐中:

>>> no_negatives(9) 
'OK' 
>>> no_negatives(0) 
'OK' 
>>> no_negatives(-1) 
'CALLING abort_on_error...' 

我知道的語法定義fail_unless是,如果你一個小技巧」不用於裝飾和功能關閉,但應用程序fail_unless()是相當不錯的沒有?

相關問題