Ash*_*ley 3 python testing unit-testing assert python-3.x
在某些情况下,我使用Doyren库(libtcod)在Python中制作了一个Roguelike游戏。我更习惯于对对象进行强类型化的C ++。
我正在编写几个类,例如GameMap,GameObject等。其中许多类都包含需要某些类型的方法,例如:
class GameMap:
...
def add_object(self, game_object, x, y):
...
Run Code Online (Sandbox Code Playgroud)
此方法将GameObject game_object添加到地图上的坐标(x,y)。显然有几种方法可以滥用此功能:
我的问题是:处理方法滥用的Python方法是什么?
我看到几种可能性:
选项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)
...
Run Code Online (Sandbox Code Playgroud)
当我将它们复制并粘贴到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)
...
Run Code Online (Sandbox Code Playgroud)
选项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)
...
Run Code Online (Sandbox Code Playgroud)
选项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
...
Run Code Online (Sandbox Code Playgroud)
选项X:还有其他东西吗?
这里的任何建议将不胜感激!我想确保我在继续的过程中遵循一种有用且可维护的模式。
断言是确保对象,结果,返回值等与我们期望的一样。尽管它们可以用于变量的类型检查,但这并不是它们的真正目的,并且它会重复。
在您的情况下,我建议使用python EAFP做事方式。让该操作在函数输入上执行,并在异常之外捕获异常。从Python词汇表:
EAFP:要求宽恕比允许容易。这种通用的Python编码风格假设有效键或属性的存在,并且在假设被证明为假的情况下捕获异常。这种干净快捷的样式的特点是存在许多try和except语句。该技术与C等其他许多语言通用的LBYL(飞跃前看)风格形成鲜明对比。
一个简单的例子:
def f(x):
"""If x is str a TypeError is raised"""
return 1 + x
try:
f('a')
except TypeError as e:
# something here or raise a custom exception
raise
Run Code Online (Sandbox Code Playgroud)