People are terrible and brains are rubbish. This is why we sometimes find ourselves sticking to what we know regardless of what's correct. People mistake common patterns in one language for common patterns in all, conflating their local scopes with globals, so to speak.
There are many examples of bad python practice that pop up regularly in dealing with new python programmers, some of which we'll go through here. Pretty much all of them are due to Java influenced source material, or just generally ignoring good python practices in favour of idioms from other languages.
Just like writing python patterns in other languages is stupid, writing other language's idioms in python is bad too.
For anyone thinking I'm about to shove PEP8 down their throats, or thinking I'm about to shove python idioms and patterns in their faces just like the very people I'm complaining about; I am not. I also am. But I also am not.
The benefit of teaching computer science through python is python's abstraction and relative simplicity. If that's ignored, you may as well use C or something. We'll take a classic anti-pattern as an example.
To teach or learn array/list iteration is to deal with a concept, not an implementation. Let's say we want to talk about iterating a list and printing each element. A phrase like "to transverse a list in sequence, printing the value of each element as you go" is more useful in expressing the idea of list iteration, than:
for ( int i = 0; i < myArraySize; i += 1 ) {
printf("%d\n", myArray[i]);
}
Following that, creating a C like index based version of list iteration in python like this:
for i in range(len(my_list)):
print(my_list[i])
is still too far from the idea expressed in our simple phrase, and is more focused on an implementation the teacher is used to, or considers more "computer sciencey". (It's also inefficient and dumb.)
Python is expressive. Python reduces the disparity between concept and implementation. Here is how it should look:
for item in my_list:
print(item)
If you're teaching a concept, lead with these simple pythonic implementations. If you want to show index based looping, just show it in C and compare them.
If you're on the learning side of this and you've been doing the
Also, for baby-budda's sake; if you have to do something involving index tomfoolery in python use
Far too often, I see code like the following from people new to python, (and those with no excuse at all):
class SomeObject:
def __init__(self, x=None):
self.x = x
def setX(self, x):
self.x = x
def getX(self):
return self.x
a = SomeObject()
a.getX()
a.setX(True)
Aside from the camelCase which is a whole realm of crimes upon its self, it has getter and setter methods.
These are terrible. Python is a Big Boy and Big Girl language for adults, who are free to access an object's attributes as they like. By simply not heaping crap on top of it, the above code can be rewritten to be faster, more useful, and more readable.
class SomeObject:
def __init__(self, x=None):
self.x = x
a = SomeObject()
a.x
a.x = True
Calling a method to access or modify an object's attribute is insane. Leave it in Java. If you have to control how an attribute is accessed, learn to use
Python does not have public or private methods. It just has methods. The single leading underscore indicates internal use, not private use. It is used to avoid importing objects from a module when the module is * imported, so as to not pollute the importer's namespace.
_SOME_CONSTANT = 42
meaning_of_life = _SOME_CONSTANT
class SomeObject:
def __init__(self):
self.x = 'lol'
self._y = 'wat'
Were you to * import the above file you would have access to
You would have regular access to
Note that if you find yourself wanting to manually modify _prefaced things, you should probably just take the code and refactor it in such a manner that any internal reliance is safeguarded from your meddling.
Double leading underscore does something very different, and generally should be avoided at all costs. It's the closest thing python has to private, but it's still not private.
class SomeObject:
def __init__(self):
self.x = 'lol'
self._y = 'wat'
self.__z = 'wow'
Here, if you want to access
Practically nobody uses this ever, and if you think your use case demands it you are probably wrong.
While we're at it, here's a link to a collection of anti-patterns.class RandomLang: def __init__(self, patterns, kws, syntax, source): self.patterns = patterns self.kws = kws self.syntax = syntax self.source = source def __contains__(self, x): return True >>> python = RandomLang(**py_stuff) >>> javaPatterns = java.getIdioms() >>> javaPatterns in python True