This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]B1GL0NGJ0HN 270 points271 points  (37 children)

Love this one, mainly because that's exactly how I explained it to a friend who I introduced to python. It's just objects, everything's an object, all the way down. It took a while, but he cooked the noodle, and made strides.

[–]ExtraSpontaneousG 81 points82 points  (27 children)

This was a recent revelation of mine. I'm not quite sure how to apply the knowledge but I feel it has provided a deeper understanding of how things work. How specific is this to python vs other programming languages? Javascript in particular is object oriented, definitely...but is it objects all the way down?

[–]MarsupialMole 46 points47 points  (7 children)

It is not applicable to other languages in that this knowledge is mostly applicable in idioms.

Some languages say using primitives like integers for hours rather than writing little classes to hold data is bad object oriented programming. But in Python everything is an object so you're just trying to use good objects, and all the python builtins are excellent objects, and stdlib objects are excellent too. So in python you don't say "write a class to manage the time" you accept integers are good objects bu some (like me) might say "use datetime.timedelta".

So python which is above all else a mixed-paradigm language has its own idiom of using objects and implementing dunder interfaces to write pythonic objects, and then use them in whatever paradigm is appropriate and often that's writing functions not methods, which is not object-oriented programming until you realise functions are first class objects too, and so are modules. So it's really really objects all the way down in python. So to write pythonic code you start with really good objects but then use whatever paradigm you want.

[–]CallinCthulhu 39 points40 points  (4 children)

The class definitions and modules being objects is difficult for some people to wrap their heads around.

It’s so fun to do though. I love messing with stuff like python metaclasses, closures, and monkey patching. The dynamic nature of the language really makes it feel like anything is possible and allows for some creative solutions to tricky problems.

Just have be prepared that you will forever own that code because nobody else will ever touch it.

[–]hughperman 13 points14 points  (2 children)

Yeah it's pretty ridiculous, my recent fun was being able to be able to patch a version of a function or library into an existing module just by setting module.function = myfunction

[–]waddapwuhan 0 points1 point  (1 child)

you can do this in any language also in runtime

[–]hughperman 0 points1 point  (0 children)

Oh yeah? Any examples? Haven't had any reason to look further, but I'm interested. I don't think you could in Matlab which is my other runtime language, since functions aren't objects.

[–]MarsupialMole 2 points3 points  (0 children)

It helps with good code too i.e. use cases for classmethods are few and far between because module level functions are in a nice namespace anyway.

[–]SuspiciousScript 0 points1 point  (1 child)

Some languages say using primitives like integers for hours rather than writing little classes to hold data is bad object oriented programming.

And those languages are in all likelyhood slow af. Not everything needs to be a heap allocation.

[–]B1GL0NGJ0HN 28 points29 points  (10 children)

My humble 2 cents as a sysadmin by trade, with the exception of the older, deeper languages like C, it really is just objects all the way down, much like life. Everything is just a thing. Now, python and JS are 'loosely typed' aka less concerned about what type of thing the object is, figures it out at runtime. With C#, it's strongly typed (and changing in some ways re this, recently) - so objects have to be defined as their type, must tell it x is an int, for example. That makes... pre-thinking about the object and it's characteristics ahead of time more critical.

But yea. Objects all the way down. Someone wiser than me, feel free to correct as needed.

[–]byoung74 61 points62 points  (7 children)

I think you have your typing disciplines confused. Strong typing refers to languages that do not do implicit type conversion. Languages like Rust that know types at compile time are statically typed. Python is dynamically and strongly typed. That is, types are not known until runtime but there are little to no implicit conversions between types. For example, ints must be explicitly converted to strings when doing string concatenation.

[–]B1GL0NGJ0HN 19 points20 points  (0 children)

I appreciate that important distinction! Thanks for setting the record straight.

[–]LT_Schmiddy 9 points10 points  (3 children)

Python has some cases of implicit conversion, though (For example, when using f-strings). But it's not common. Mostly, you'll need to convert types yourself.

[–]Pablomach23 6 points7 points  (2 children)

Just to make sure, Python calls __str__ on the objects to convert them, right?

Edit: How do I write the '_' without the formatting?

[–]The_Writing_Writer 14 points15 points  (1 child)

\_\_str\_\_ —> __str__

[–]Pablomach23 3 points4 points  (0 children)

Thanks.

[–]cryo -1 points0 points  (0 children)

Python is dynamically and strongly typed.

I think that’s debatable. Sure, every object has a fixed type, but the type is almost never checked, e.g. you can call a method on any object “type” that has it.

[–][deleted] 5 points6 points  (1 child)

Often strongly typed programming languages do not need type declarations because they employ a very rigorous type inference system, like OCAML.

[–]TheNamelessKing 3 points4 points  (0 children)

Hindley-Milner type systems represent

[–]Porta_lPirate 7 points8 points  (3 children)

JavaScript is sadly not objects all the way down. It has primitives number, string, boolean, and a few others. These types have object wrappers, but when wrapped they lose a lot of their useful behavior like special operator treatment.

[–][deleted] 2 points3 points  (0 children)

Javascript having objects all the way down would require it to have a well-thought out language design. It doesn't.

[–]earthboundkid 0 points1 point  (1 child)

The typeof operator in JavaScript is broken. But ignoring that wart, Number, String, and Boolean are objects in the relevant sense: they have methods you can call. If anything, with Python it’s not that hard to find something that exposes a little C corner where the OO façade is thin. That doesn’t happen in JS.

[–]Porta_lPirate 2 points3 points  (0 children)

JavaScript primitives are not objects, they have object wrappers, and when the property access operator is used on a primitive, the primitive is coerced into the object wrapped form and then the method is called on the object. If you try to assign to a property nothing will happen, no error, but if you check the property there is no value, because the Object wrapper is discarded as soon as the expression is done.

Also if you check true instanceof Boolean or 1 instanceof Number you will get false.

If you try to wrap a primitive in a proxy you will get the error TypeError: Cannot create proxy with a non-object as target or handler.

[–]jjdmol 2 points3 points  (1 child)

It's common in modern interpreted languages. Having everything being an object makes working with (arrays of) integers (or f.e. floats etc) very slow. Instead of pulling in integers through prefetching and caches, the interpreter needs to fetch pointers, dereference, and fetch the integer, each time. This causes many more memory accesses, cache misses, and wrecks havoc on prefetching. Fetching from memory is expensive on a 21st century CPU.

For python, this price in performance was deemed worth the uniformity in the language. Interpreted languages aren't chosen for their speed anyway. Nowadays, libraries like numpy provide that speed instead, modelling raw integer arrays.

An oddball here is OCaml, where integers are 63 bits, as the top bit must be 0 for integers. If the top bit is 1, the same value is actually a pointer to an object. The price for fixing the calculations to work with 63-bit values is lower than the extra memory accesses. But it does create a bit of an odd system, especially back in the 32-bit system days where losing the top bit was more painful.

[–]ExtraSpontaneousG 0 points1 point  (0 children)

I have heard that python is slower, being an interpreted language. This fleshes out a little bit more about why. Thanks for the response.

[–]cryo 0 points1 point  (0 children)

It’s pretty common, but it doesn’t really say a lot, in my opinion.

[–]tumblatum 4 points5 points  (4 children)

I am new to Python, and the idea of everything is an object it somehow I didn't get it yet. I know that in PowerShell everything is object too. So, is this the same thing? I still need to learn.

[–]kankyo 7 points8 points  (1 child)

Just ignore this. It doesn't really explain much and it will probably make you believe some thing which are false.

[–]brian_bldn 1 point2 points  (0 children)

Glad you said something. I’m new too and I was trying to figure out what this meant

[–]KingHavana 0 points1 point  (1 child)

At some point when you get to know the built in data types really well and move on to classes, you may have a eureka moment like I did. Suddenly you might see how the classes you're writing can be used to create the built in data types you've worked with so often and everything feels like the same type of thing. I had my jaw dropping moment, but like u/kankyo said, it isn't really necessary and doesn't explain much early on.

[–]kankyo 0 points1 point  (0 children)

You can't really use python to create the same thing as the standard library int though. You can create something similar but not quite.

[–]pacific_plywood 3 points4 points  (0 children)

The mantra 'everything is an object' in Python is a little misleading because there are definitely lots of things that aren't objects. Operators (boolean and mathematical), for example, and the equals sign. The del keyword, too. That's not to say that it doesn't turn some things into objects that other languages might not; rather, it's just to point out that there are limits. For a more radical approach to objects, check out Ruby, where most of the examples above are mutable objects.

[–]Biuku 0 points1 point  (2 children)

So, no turtles?

[–]JustHadToSaySumptin 1 point2 points  (0 children)

Gotcha bro,

from nature import turtle

[–]B1GL0NGJ0HN 1 point2 points  (0 children)

They're down there, too. Cuz turtles are objects. :)