![User banner](https://pawb.social/pictrs/image/09c585ae-d0d1-4687-b80b-b2eb11da8ce0.jpeg)
What kind of soulless psychopath leaves a window of this size unmaximized is the real question here. Also, a horizontal scrollbar in the main section, able to scroll maybe 8 pixels total to see some more of the glorious empty padding, could have been a nice touch as a consequence of the "unintended" window size.
I would not differentiate needlessly between the terms function and ["dunder", "instance", "module", "class"] method, this isn't practical at the current point in time, and arguably not pythonic. They are all callables
and behave very similar for all practical purposes, all quacking like a duck.
If you want to deep-dive into the intricacies, there's technically a bunch of alternative "method types" with slightly differing calling and argument passing conventions. There are class methods, static methods, class properties, and module-scope functions off the top of my head, all very similar, but particularly suitable under specific circumstances.
If I wanted a String
utility class, for example, I could have that:
class String:
@staticmethod
def len(string: str) -> int:
if not isinstance(string, str):
raise TypeError("Cannot determine length of non-string object")
return len(string)
s = "foobar"
assert String.len(s) == 6
In Python I generally find static methods hardly as relevant as in other languages, and tend to create utility modules instead, with plain functions and maybe dataclasses for complex arguments or return values, which can then be imported and called pretty much the same way as a static method, but without the extra organisational class layer. I'd argue that's very much a matter of taste, and how much of a purebred OOP jockey you are, for better or worse.
Class properties are cool, however, you might want to look into that. It's getters/setters on crack, masquerading as their respective property, so that something like this "just works":
s = MyString("foobar")
assert s.len == 6
Are there any other ways I would find the length? Or are methods and functions the only options?
You could get creative and find several inferior, silly, and utterly insane ways of achieving the same result, for example by treating a string as an interable (read: "list" or "array") of its constituent characters, and count the number of characters. This feels very "example (but not exemplary) code on the first pages of a crappy C++ textbook", but hey, it's a way:
length = 0
string = "foobar"
for char in string:
length = length + 1
print(length)
Mind you, this is not programming. This is toying around, and perfectly valid in that way, but no-one in a halfway sane state of mind would dare suggest doing it this way with Python if you actually care about the result. :)
Are there any other ways I would find the length? Or are methods and functions the only options?
You could get creative and find several inferior, silly, and utterly insane ways of achieving the same result, for example by treating a string as an interable (read: "list" or "array") of its constituent characters, and count the number of characters. This feels very "example (but not exemplary) code on the first pages of a crappy C++ textbook", but hey, it's a way:
length = 0
string = "foobar"
for char in string:
length = length + 1
print(length)
Mind you, this is not programming. This is toying around, and perfectly valid in that way, but no-one in a halfway sane state of mind would dare suggest doing it this way with Python if you actually care about the result. :)
What is the difference between these types of statements?
Technically, len()
is a Python built-in function, while "some string".len()
would be an instance method of a string object, if such an instance method existed.
How do I think about this to know which one I should expect to work?
As a very general rule of thumb, I would recommend to keep the list of built-in functions close and memorize the "popular ones" over time. These are special. Anything else you encounter usually is an instance or class method, or a plain function without any object-oriented shenanigans, depending on how structured the code is you are looking at.
Learn to navigate the Python reference docs. Use the search function liberally if you don't come from a search engine result, anyway, or jump directly to the docs for the module you're interested in to see what functionality it offers, and how to use it.
Python is annoyingly flexible, and does not strictly enforce a single way to do anything, so learning what to expect always ends up as building an intuition, and actively looking up documentation for the modules, classes, or functions you intend to use until you have encountered enough (good) Python code to have reasonable expectations in the first place.
TL;DR: grep the relevant module's docs, or Python built-ins. It's typically one or the other where you find detailed help.