Trey Hunner Profile picture
Jul 19, 2022 β€’ 11 tweets β€’ 5 min read β€’ Read on X
class: a template for creating an object

We've defined instance and method. For this week's #TerminologyTuesday, it's finally time to define the word "class" in #Python. πŸ“•πŸ

Where do classes come up and how do they work? πŸ€”
The terms "class" and "type" are synonyms in Python.

The type of an object is its class and an object's class is a "type".

As we discussed when we defined "class instance" last week, every object in Python has a class. That means classes are EVERYWHERE in Python.
list, dict, int, str, tuple, bool, set, and float are all classes.

But (somewhat strangely) range, enumerate, zip, reversed, and type are also classes. 😦 Huh?

We often don't care whether an object is a class or a function in Python. Both are callables. πŸ‘‡
When you call a function, the function runs and you get back the return value of that function.

When you call a class, a new class instance is constructed, initialized, and returned to you.

So in Python, we often don't care whether a callable is a class or a function...
As long as we know how to work with the return value of a callable, whether the callable is a class or a function is just an implementation detail.

We do *sometimes* care whether a variable points to a class or function, but not often.
So classes are everywhere. And classes (like functions) are callables.

But what are they for?

Classes are most often used for coupling state and functionality.

Instead of passing a dictionary of values into many functions, we can make a class instance and call methods on it.
Wondering what a method is?

I defined that term a couple weeks ago.

Essentially a method is a function that's defined on a class and meant to operate specifically on instances of that class.
Class instances store data. And classes typically have methods that operate on that data.

Though classes are sometimes used *just* for their data.

If you're making a class *just* for its data, you may want to look into dataclasses.

pym.dev/dataclasses/
Classes usually involve both functionality (methods) & state (attributes on each instance).

Some classes are all about state, but they should never be all about methods.

A class of just methods should be a function. An oldie but goodie talk on this. πŸ‘‡

pyvideo.org/pycon-us-2012/…
So calling a class makes an instance of that class. And classes typically have methods on them.

There are 3 methods I recommend implementing on every class.

The first is __init__ (the initializer).

I also recommend __repr__ & __eq__ to make your classes friendly to use.
There's *so* much more to say about classes in Python.

Here's a few places to start:

➑️ pym.dev/what-is-a-clas…
➑️ pym.dev/classes-are-ev…
➑️ pym.dev/what-is-self/?…
➑️ pym.dev/what-is-init/?…
➑️ pym.dev/inheriting-one…

And more here πŸ‘‡
pym.dev/screencasts/cl…

β€’ β€’ β€’

Missing some Tweet in this thread? You can try to force a refresh
γ€€

Keep Current with Trey Hunner

Trey Hunner Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @treyhunner

Mar 14, 2023
Instead of getter and setter methods, in #Python we often use a property to control what happens when we get/set a specific attribute.

>>> r = Rectangle(5, 4)

With a property, instead of this:

>>> r.get_area()
20
>>> r.set_area(8)

We can do this:

>>> r.area
20
>>> r.area = 8 Image
You can think of a property as a virtual attribute.

Accessing a property runs a function. And so does assigning to a property!

Don't believe me? Try running this and take a look at what's printed.

pym.dev/p/2krm5/
By default a property can be read from but not written to.

class Circle:
def __init__(self, r):
self.r = r
@‍property
def d(self):
return self.r*2

>>> c = Circle(2)
>>> c.d
4
>>> r.d = 5
AttributeError: property 'd' of 'Circle' object has no setter
Read 4 tweets
Mar 10, 2023
In Python we don't have "main" functions.

Instead we ask the question "is my module the entry point to this #Python process?"

We do that with this very strange looking condition:

if __name__ == "__main__":
main()
Why does this work? πŸ€”

Well, each module has a __name__ variable in it which represents the name of that module. There's also __file__, which is its file path and __doc__ which is its docstring.

But when Python runs a module as a script, it does something different...
Every #Python process has one module which acts as its entry point.

When you run "python3 my_script.py", you're telling Python to use the my_script.py file as the entry point module.

The entry point module doesn't get its own name, but a special one instead: "__main__".
Read 6 tweets
Mar 9, 2023
There are 3 methods I implement on most #Python classes I make.

β€’ __init__: the initializer method
β€’ __repr__: the programmer-readable string representation
β€’ __eq__: implement a nice sense of equality (what the == operator does)

__init__ & __repr__ always, __eq__ usually
If you're inheriting from another class you'll likely get some (or all) of those for free.

But if you're creating your own class, it's easy to overlook __repr__ and even easier to overlook __eq__.

But both of those methods can make it easier to work with your class instances.
The tricky one of those 3 methods is __eq__.

Not all classes really have a sensible notion of equality outside of the "equality is identity" behavior that Python provides out of the box.

And implementing __eq__ makes objects unhashable by default, though that's rarely an issue.
Read 5 tweets
Mar 8, 2023
Need to de-duplicate items in a list?

>>> my_items = ["duck", "mouse", "duck", "computer"]

This works if you don't care about the order:

>>> unique_items = set(my_items)

If maintaining item order is important, this works:

>>> unique_items = list(dict.fromkeys(my_items))
Confused by list(dict.fromkeys(...))?

dict.fromkeys() accepts an iterable and creates a new dictionary with the iterable items as keys and None as the values.

list() accepts an iterable and creates a new list from its items

When you loop over a dictionary you get just the keys
That dict technique works because dictionaries have unique keys and dictionaries maintain the insertion order of their items.

Note that those two techniques only work for numbers, strings, or other hashable objects.
Read 4 tweets
Oct 3, 2022
Need the largest item in an iterable in #Python? 🎚️

>>> max(iterable)

Need the largest n items in an iterable? ⬆️

>>> from heapq import nlargest
>>> nlargest(n, iterable)

Need all items arranged from largest to smallest? πŸ“‰

>>> sorted(iterable, reverse=True)
Need the smallest item in a #Python iterable? βš–οΈ

>>> min(iterable)

Need the n smallest items? ⬇️

>>> from heapq import nsmallest
>>> smallest(n, iterable)

If you need all of them in increasing order, use sorted (no reverse) πŸ“ˆ

>>> sorted(iterable)
Here's a sort of cheat sheet for getting the smallest & largest items in #Python πŸ—’οΈπŸ

Click the big green button to run the code 🟒

Feel free to bookmark it for the next time you need this πŸ”–

pym.dev/p/39jsj/
Read 5 tweets
Sep 7, 2022
Python's "for" loops can only loop in one direction: forwards!

If you need to loop in the reverse direction, the built-in "reversed" function can help.

>>> colors = ["pink", "blue", "green"]
>>> for color in reversed(colors):
... print(color)
...
green
blue
pink
The "reversed" function only works on reversible iterables.

Fortunately, most of the iterables you might care to reverse *are* reversible.

Sequences (e.g. lists, tuples, and strings) are reversible and so are dictionaries (as of Python 3.8).
Python's "for" loops are single-purposed: they can loop over an iterable 1 item at a time.

That's why these built-in looping helpers (and others) are such a big deal:

β€’ reversed: loop in reverse
β€’ enumerate: count upward while looping
β€’ zip: loop over 2+ iterables at once
Read 4 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us!

:(