There’s the old joke about 10 kinds of programmers, but the truth is when it comes to programming, there are often people who make tools and people who use tools. The Arduino system is a good example of this. Most people use it like a C compiler. However, it really uses C++, and if you want to provide “things” to the tool users, you need to create objects. For example, when you put Serial in a program, you use an object someone else wrote. Python — and things like Micropython — have the same kind of division. Python started as a scripting language, but it has added object features, allowing a rich set of tools for scripters to use. [Damilola Oladele] shows the ins and outs of object-oriented Python in a recent post.
Like other languages, Python allows you to organize functions and data into classes and then create instances that belong to that class. Class hierarchies are handy for reusing code, customizing behavior, and — through polymorphism — building device driver-like architectures.
For example, you might build a class for temperature sensors and then create specialized subclasses for different specific sensors. The code to convert the sensor reading to degrees would live in each subclass. However, common code, such as getting an average of several samples, could be used in the main class. Even more importantly, any part of your code that needs a temperature sensor will just deal with the main class and won’t care what kind of sensor is actually in use except, of course, when you instantiate the sensor.
Python’s implementation of object orientation does have a few quirks. For example, if you create a class variable, it can be read from a subclass without specifying scope like you’d expect. But if you try to write to it from a subclass, you create a new variable for that particular subclass, which then hides the parent class version.
Still, objects can make your tools and libraries much more reusable, and Python makes it relatively easy compared to some other languages. If you want to see how objects can improve common constructs like state tables, you’ll have to read a different language. If you want to see an admittedly hairy Python example, check out VectorOS, the operating system for the 2023 Hackaday Supercon badge.
I object to objects being an object in that title! 😆
I have worked places where we programmed using object methods. Somebody would propose something and then everyone else would object. LOL
🤦♂️
C++ objects don’t match the metaphor for “things” that people interact with. C++ objects are a type of organizational structure for the developer and are pretty abstract when compared with the actions or verbs that a user might want. To successfully make a program that interacts well with a user, you need to implement this missing aspects on top of what C++ already gives you. Because it’s not baked in.
SmallTalk is much closer to the metaphor of objects in the sense that a user internalize than C++. And it’s good at what it does, but it isn’t good at everything, like being small and fast, or at incorporating lots of third-party libraries.
I think only a Python user would appreciate the way Python handles the concept of objects. It’s not for everyone. There’s some ugly bits like def __init__(). And a lack of a common base class that makes SmallTalk, Objective C, and Java so hierarchical and fairly easy to explain. But you can write up something straight forward in Python in fewer lines and with far less boiler plate than it would take in C++ or Java. Something like Scala is a nice compromise between extremely verbose Java and something a little more rigorous than Python’s runtime type system.
I was thinking more of “things” developers interact with. For example, I want to use a serial port. I don’t care if it is a USB port, a UART, or serial bit banged. So… SerialPort *p=new UARTSerial(…); and from then on … p->send(…) or whatever. Even if later, I change to new USBSerial… etc.
Calling a method call a ‘message’ doesn’t actually do anything.
“and a lack of a common base class”
That changed years ago (python 2.2!). All classes in python 3 derive from “object” if not given a parent class.
Good to know. I quit learning Python when releases kept breaking my production code by when we were at the mercy of the bundled “system Python” and would take out parts of the distro if we installed a second one (that’s the distro’s fault, not python’s).
I’m going to wait a few decades for the language to settle down before I invest any more time into it. There’s so many other interesting things to play with that are more semantically stable.
pyevn and the built in venv solve all of that. Similar to nvm for node.js
Ubuntu 23.04 and newer at least stops your from installing pip packages into the system environment now. It’s much more difficult to break the system python environment.
I like pip/pip3. Works well. Just recently I ran into a package that Ubuntu 24.04 (and 23.10) didn’t support, so had to ‘force’ the pip3 to just install it. Worked just fine. I know canonical did it for security reasons to use apt install python3-, but…
“I quit learning Python when releases kept breaking my production code”…
Knock on wood, I have not experienced that problem with Python 3. Of course I don’t use any of the ‘fancy’ language features. Just the basic stuff. Easier to follow doing it that way.
My take on OO in arduino: https://paulmurraycbr.github.io/ArduinoTheOOWay.html .
A lot of the time, I learn something when reading HaD articles. Mostly (being an uneducated barbarian), large portions of what is assumed to be basic knowledge here leads me to research things I don’t understand (mostly everything ), and move me ever so slightly forward in my understanding of areas I am not an expert in, but want to suck less at (EE / hardware / circuits / stuff people go to school for)
As someone who loves python, and taught myself OOP using it, I’m a little surprised to see an article that basically says ‘python has objects and they have a use’. Maybe it’s just a case of running into knowledge I already have and therefore assuming that it’s universal (like everyone here seems to assume a good home and schooling for understanding basic circuits), but this seems like pretty basic stuff for 2024.
Forgive me for my arrogance, as I mostly feel like a dumb**** reading stuff here, just saying to me this seems like simple background info.
It’s simple background info for us, but some people’s favorite programming language is solder, and they only use code when they can’t fit enough 555s to do something.
Objects are still somewhat obscure to a total nonprogrammer.
I’m with you. This article is weird. “Python has objects” isn’t even catching it properly. As in python, EVERYTHING is an object. Strings, an object. Modules, objects. Integers and floats, you got it, they are actually immutable objects.
(cpython implementation details aside, where it optimizes ints/floats to be more efficient then “pure” objects)
Even operators are objects!
There’s two types of programmers in this world: ones who verbosely add explanatory comments throughout every line their code, and ones who just have the code.
I’m in between.
I tried to be the guy that adds a lot of comments and inline docs. That got old fast!
…but not as old as I am, which is why I add all of those comments (…and, if you don’t understand this comment, be assured that you will; you will) :-)
I add comments any time anything isn’t exceedingly obvious, because I know most of it won’t necessarily be obvious to anyone else looking at it, or even myself if I haven’t looked at it in a month or so.
In my experience, there are programmers that write good comments, and programmers that are on someone’s hitlist for not doing so.
It doesn’t need to be EVERY line.
But it should be as often as feasible.
Trying to mentally parse spaghetti code sucks and makes you hate the person who wrote it.
It still sucks when that person is you.
Objects don’t scale as well as procedures.
Do the thought experiment about what would happen when objects within objects are taken to the limit, as opposed to procedures calling procedures ad infinitum.
With objects, due to information hiding there is a progressive occlusion of program state resulting in something analogous to the effect of a cataract on vision.
Due to accessor function overhead there is also a progressive paralysis as objects are encapsulated to the limit.
There needs to be a ‘balance’. We have a program at work that was ‘objectized’ to death. Very hard to figure out what is going on when one needs to make a change. We grumble every time a change is needed…. No one wants to take ownership. In projects that are embedded I tend to not create objects (use like straight C functions/procedures) just for lower overhead. In a desktop/server I use it objects when they ‘make’ sense to do so. Not just because I can. Hope that makes some sense. Balance is the key to good readable, functional code.
Balance with comments too. Use variable names that are self documenting. Then you have less documenting to do. And be reasonable. Don’t use 256 chars for a variable name… To verbose can be worse than not enough. Balance.
For example: totalMWh = unit1MWh + unit2MWh + unit3MWh;
Not : t = a1 + a2 + a3
I consider three characters a minimum for variables. Reason is that with 3 characters, highlighting of where a variable is used in a section of code works properly. A bunch of IDE’s also do auto highlighting after the third character.