對於某些情況下,我使用Doyren庫(libtcod)在Python中製作Roguelike遊戲。我更習慣於C++強對象類型的對象。什麼時候應該在Python中使用'assert'?
我寫了幾類,如GameMap,遊戲物體,等等。許多這些類的含有期望某些類型的方法,例如:
class GameMap:
...
def add_object(self, game_object, x, y):
...
這種方法增加了遊戲對象game_object到座標(x,y)在地圖上。顯然有多種方式這個功能可以被濫用:
- 非遊戲對象可以作爲game_object
- 的非整數可以爲x或y
- 負整數,可以作爲傳遞傳遞傳遞x或y
- 一個整數,它超出了地圖的寬度可以爲x
- 一個整數,它超出了地圖的高度可以爲y傳遞被傳遞
我的問題是這樣的:處理方法濫用的Pythonic方法是什麼?
我看到幾個可能性:
選項1:奠定了一系列的斷言在方法的開始:
def add_object(self, game_object, x, y):
assert(isinstance(game_object, GameObject)
assert(type(x) == type(y) == int)
assert(0 <= x < self.map_width and 0 <= y < self.map_height)
...
這些斷言得到相當重複的,因爲我複製+粘貼它們到我在GameMap中的許多方法中,這就是爲什麼我還提供選項2:
選項2:在自己的函數中編寫斷言,然後調用這些斷言需要防止當拷貝+粘貼
def check_game_object(self, game_object):
assert(isinstance(game_object, GameObject)
def check_coordinate(self, x, y):
assert(type(x) == type(y) == int)
assert(0 <= x < self.map_width and 0 <= y < self.map_height)
def add_object(self, game_object, x, y):
check_game_object(game_object)
check_coordinate(x, y)
...
選項3:鋪陳一系列自定義異常的在方法的開始:
def add_object(self, game_object, x, y):
if not isinstance(game_object, GameObject):
raise InvalidParameterException("game_object not a GameObject")
elif not type(x) == type(y) == int:
raise InvalidParameterException("(x, y) not integers")
elif not (0 <= x < self.map_width and 0 <= y < map.self_height)
raise InvalidMapCell("x, y do not represent a valid map cell)
...
選項4:返回失敗指示符,並在更高級別處理問題
def add_object(self, game_object, x, y):
if not isinstance(game_object, GameObject):
return False
elif not type(x) == type(y) == int:
return False
elif not (0 <= x < self.map_width and 0 <= y < map.self_height)
return False
...
選項X:別的嗎?
任何意見在這裏將不勝感激!當我繼續時,我想確保我遵循一個有用且可維護的模式。
斷言是** **不驗證參數。它們用於確保外部非用戶對象符合預期。 –
謝謝你的建議。是否有另一種Pythonic方法來強制使用正確的方法? – Ashley
在Python中執行此操作的常用方法是僅使用該對象並捕獲任何生成的異常。 –