I've got a 2D array of different blocks, all inheriting from Block. I want to check if the block that I clicked on is a Dirt type block, like this:
clickedblock = getClickedBlock()
if isinstance(clickedblock, Dirt):
place a block
else:
don't place a block
I've heard that isinstance
is bad, and should be avoided because it creates forks in code. What times would isinstance
be good to use?
Another more cumbersome solution for my problem would be to have a field of Block called 'id' and then check if it equals some constant that means Dirt. But that sounds quite bad and more prone for mistake than the simple isinstance
.
Your example seems like a legitimate use case of isinstance()
.
It's not that isinstance()
is bad, often polymorphism can be used for the same purpose (which results in cleaner code in where the class is used).
But sometimes, isinstance()
is what you need. For example, the pythonic way of detecting whether a variable is string or not is isinstance(var, basestring)
.
I learned the hard way against using it. The problem is that the outcome is sensitive to how the class definitions were imported:
isinstance
test is performedIf one import was relative and the other absolute - the check will fail.
Essentially it'll be like checking on equality between SomeClass
vs somepackage.SomeClass
. It doesn't even matter that they come from the same file and so on. Also, there will be a similar outcome if you somehow have both the root directory and somepackage
directory in your PYTHONPATH
- then an absolute-styled import could denote a path from either of the "source roots" so two different absolute-styled imports would result in failing instance checks.
One could argue about how good practices would anyway prevent that from happening but good practices are also largely about not taking chances. In that spirit I prefer to put some abstract method in a common ancestor class so that I can later rely on how things quack rather than on what the interpreter believes them to be.
In Java each class resolves to its fully qualified class name. These are unique within a program and tests for instances are a breeze. In Python these can be slippery.
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