My current situation is involved in making a game in python using a library called pygame. I have a method called getTile() that returns the tile every time the player moves. The lvlDict makes up the world.
def getTile(self, pos):
x = pos[0]
y = pos[1]
return self.lvlDict[x,y].kind
and i'm thinking about changing it to this
def getTile(self, pos):
try:
x = pos[0]
y = pos[1]
return self.lvlDict[x,y].kind
except KeyError:
return None
where there would be some interpretation for what to do if it were None. Likely just move back to where it previously was. Is this inherently bad or acceptable? Even if it's just a matter of opinion, I'd like to know what people think about it.
Another disadvantage of passing and catching Exception (or bare except ) is that we will never know the second error when there are two errors in the code. The first error will always be caught first and we will get out of the try block.
The reason to use try/except is when you have a code block to execute that will sometimes run correctly and sometimes not, depending on conditions you can't foresee at the time you're writing the code.
When an exception is thrown using the throw keyword, the flow of execution of the program is stopped and the control is transferred to the nearest enclosing try-catch block that matches the type of exception thrown. If no such match is found, the default exception handler terminates the program.
Exceptions are the conditions that occur at runtime and may cause the termination of the program. But they are recoverable using try, catch and throw keywords.
In this case, I think asking for forgiveness is better than asking for permission on the off chance that something happens to your dictionary between check and indexing, but in general, I tend to prefer not using exceptions for logic, entirely because exceptions are bloody slow.
In [1]: d = {i:i for i in xrange(10000)}
In [4]: def f(d):
try:
d["blue"]
except KeyError:
pass
In [5]: def g(d):
if "blue" in d: d["blue"]
#Case: Key not in Dict
In [7]: timeit f(d)
1000000 loops, best of 3: 950 ns per loop
In [8]: timeit g(d)
10000000 loops, best of 3: 135 ns per loop
#Case: Key in Dict
In [9]: d["blue"] = 8
In [10]: timeit f(d)
10000000 loops, best of 3: 151 ns per loop
In [11]: timeit f(d)
10000000 loops, best of 3: 151 ns per loop
Exceptions are slow so it's best to save them for truly exceptional circumstances. If it's an unexpected situation that doesn't normally crop up, then an exception is sensible. If an empty tile is a common occurrence it would be better to use an if
check instead.
Another way to look at it is whether the user can trigger it or not. If the player can cause this condition merely by moving around the map, it probably shouldn't be an exception. Exceptions are more appropriate for when you encounter unexpected cases that aren't the user's fault, such as "oops, I forgot to put a wall here and the player wandered off the map" or "I expected this file to be there and it wasn't."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With