Introduction to Object Oriented Programming in Python
stackabuse.com
stackabuse.com
This is a common, but dangerous way to introduce the object-oriented paradigm. While it is true that many object-oriented systems end up having a few classes that represent entities of its problem domain (such as, perhaps, bus stations in a public transport app), most of them do not. These other classes are abstract entities like data repositories, factories, controllers etc. that are meant to split software into understandable pieces with clear responsibilities that work together to make things happen.
The point is that this collaboration happens solely by these pieces sending each other messages (calling methods) that describe their intent, without needing to know how exactly the message is being processed. This style of communication is the key characteristic of object orientation, and even an introduction should probably put their focus on this aspect rather than „modeling the real world“, which isn‘t really something that is done this way in practice.
All this being said, I do see the appeal of the real-world rhetoric in that it seems much more approachable than ralking about little communicating abstract things. I wonder how to balance this.
But I also think the "message passing" metaphor has outlived its usefulness the same way. A caller does not need to know how the callee is implemented. Sure, but this is the same in any language with functions/procedure, this is not something specific for OO. The idea of message passing is a bit deeper, for example that the client does not even know it is calling a method. It sends a message, and the object answers, even if it is just by throwing an error that the message is not supported. This is how Smalltalk and (I think) Ruby works, but not at all how a statically types language like C# works. And it is not how Python works either. In Python you obtain a method reference from an object and then invoke it. So if you apply the message passing metaphor, your are actually passing the message to the method rather than the object itself. Which I think is just a confusing way to describe a method call.
I can approach writing Python essentially the same way I’d write Haskell using the above strategy. I think it looks really nice.
I’ve turned a few people away from the dark path of OOP by writing in this style as well. They’re usually turned when they see how easy it is to test just regular functions with no need for magic mocks and the like.
Checkout http://wiki.c2.com/?ClosuresAndObjectsAreEquivalent
FP is also quite idiomatic. Pythons list comprehensions are quite powerful, and the libraries I mentioned in my previous comment are all part of the standard library. There are third party libraries that attempt to make Python even more functional.
I wouldn't like to maintain Haskell code written by someone who thinks everything should look like Python. And vice-versa.
Python is a multi-paradigm language. I have not found Python to be better at OOP versus imperative or functional styles of programming.
For me, functional programming provides a closer to model to how I think about problems. This is true for many people. One should choose the style that provides the easiest translation of thought to code.
It’s so hard to even check where the actual implementation is....
There are no comments in code, no documentation whatsoever...
Refential transparency and simple data structures makes code much simpler to understand, and leads to fewer surprises when the code is being modified.
Anyone who learns Python will necessarily learn OOP as it’s the de facto style. The post is a resource for that. My comment is meant to encourage people to consider the alternative ways you can approach problems in Python.
>>> def odd(n): return n % 2 == 1
...
>>> [ i if odd(i) else -i for i in range(1, 11) ]
[1, -2, 3, -4, 5, -6, 7, -8, 9, -10]
In [8]: f = lambda x: x * 2
In [9]: f(2)
Out[9]: 4
In [10]: g = lambda x: if x % 2 == 0: x * 2 else x * 3
File "<ipython-input-10-f7248669b8fd>", line 1
g = lambda x: if x % 2 == 0: x * 2 else x * 3
^
SyntaxError: invalid syntaxYou can write python in a functional style, but you're still going to use OOP constructs.
> from inspect import type
> type([])
=> <class 'list'>
> type(lambda x : x)
=> <class 'function'>
> type(1)
=> <class 'int'>
> type([x * x for x in [1,2,3]])
=> <class 'list'>
> type((x * x for x in [1,2,3]))
=> <class 'generator'>
> ...