2017-09-24 104 views
1

在紅寶石(on Rails的,實際上),我有try功能:從Ruby到Python - 有沒有相當於「try」的東西?

[].try(:[], 1) # => nil 
[10].try(:[], 1) # => nil 
[10, 20].try(:[], 1) # => 20 
[10, 20, 30].try(:[], 1) # => 20 

{}.try(:foo) # => nil 
{ foo: 'bar' }.try(:foo) # => 'bar' 

的功能基本上是快捷方式,以避免if s到檢查位置是否存在。
Python中是否有類似的東西?

+5

看起來你有點誤解了'嘗試'在Rails中的用途。在Ruby中對無效索引進行數組查找會返回'nil'而不是引發異常,因此不需要'try' [10] [1]#=> nil'。嘗試進入以避免在「無」結果時調用方法的錯誤,例如'[10] [1] + 3#=> NoMethodError:未定義的方法'+'爲nil:NilClass'但是[10] [1] .try(:+,3)#=> nil'(沒有例外) – mikej

+0

如果你的問題得到解答,你可以[接受最有用的](https://stackoverflow.com/help/someone-answers)。 –

回答

3

字典

您可以使用dict.get

d = {'foo' : 'bar'} 

print(d.get('foo')) 
'bar' 

print(d.get('xxxxx')) 
None 

你也能傳遞一個默認參數get

print(d.get('xxxxx', 'Invalid Key!')) 
Invalid Key! 

默認值將被打印出來的時候,關鍵不不存在於字典中。


列表

你必須使用一個try-except塊,因爲list秒到不具有直接的等價物。

def list_get(l, idx, default=None): 
    try: 
     return l[idx] 
    except IndexError: 
     return default 

l = [10, 20] 
print(list_get(l, 1)) 
20 

print(list_get(l, 2))  
None 
+0

如果我正確的理解了OP,他還需要'list'這樣的'list'類型 –

+0

@BearBrown正在編輯它。 –

1

用dict的,你可以使用d.get('foo'),如果該鍵不存在,它將不返回任何內容。您還可以指定一個默認值d.get('foo', 'bar'),在這種情況下,如果密鑰foo不在字典中,則會返回bar

有了列表,就沒有這麼明顯的辦法。你可以定義一個簡單的函數,

def check_item(list_obj, item): 
    try: 
     return list_obj[item] 
    except IndexError: 
     pass 

哪個會返回值,如果它存在,沒有,如果不是。然後簡單地稱它爲value = check_item(list_item, item_to_look)


更高級的選擇是將子類list類,並重寫__getitem__方法用類似的邏輯與上述的功能。 (它需要一些額外的修改來處理slice對象等)

1

python list object has no safe .get like dictionary has。

你需要趕上用自己的嘗試,除了:

try: 
    return your_list[index] 
except IndexError: 
    return default # could be -1 for example 
0

在Python中,您必須通過這個口頭禪生活「它更容易請求原諒比獲得許可」。

然而,對於一個列表,你可以寫一個這樣的檢查,使列表成爲一個字典,其索引作爲關鍵字。

>>>en = enumerate([10, 20]) 
>>>dct = dict(en) 
>>>dct.get(2) 
None 
>>>dct.get(1) 
20 
0

組合解決方案

def safe_get(data, key): 
    if isinstance(data, (list, set, tuple)): 
     return dict(enumerate(data)).get(key) 
    elif isinstance(data, dict): 
     return (data).get(key) 
    else: 
     return None 

print safe_get([], 1) 
None 
print safe_get([10], 1) 
None 
print safe_get([10, 20], 1) 
20 
print safe_get([10, 20, 30], 1) 
20 
print safe_get({}, 'foo') 
None 
print safe_get({ 'foo': 'bar' }, 'foo') 
bar 
1

不可能有像在Python try一個方法中,由於try關鍵依賴於猴修補ObjectNilClass,以及它們的Python當量(objectNoneType)不能被猴子修補:

def try_object(self, f, *args, **kwargs): 
    return getattr(self, f)(*args, **kwargs) 

def try_none(self, f, *args, **kwargs): 
    return None 

object.try = try_object 
object.try = try_object 
#   ^
# SyntaxError: invalid syntax 

NoneType.try = try_none 
#   ^
# SyntaxError: invalid syntax 

但是,你可以編寫一個全球的try功能,其行爲類似:

def tryy(obj, f, *args, **kwargs): 
    if obj is None: 
     return None 
    else: 
     return getattr(obj, f)(*args, **kwargs) 

tryy([10, 20], '__getitem__', 1) 
# >>> 20 

tryy(None, '__getitem__', 1) 
# >>> None