##  [Getting started with classes in Python Part 1: Anatomy of a Class](/blog/getting-started-classes-python-part-1-anatomy-class) 

In Python you may hear this phrase said a lot "everything is an object", which they are! Objects, that is. But what this *means* is that **everything** is *really* (if you look 'under the hood') either a class, or an instance of a class ("but what does *that* mean?!", don't worry, we'll get there). Once you have learnt how to make classes, and manipulate them, you gain the ability to create your own objects as well as *edit* existing ones as you may like. Now, this is **a lot** and naturally with great power comes great responsibility and it would be remiss for me to explain how you can break everything without explaining how to fix it as well.

However, ultimately, all this wild potential is well beyond even intermediate level and when you're just starting out you really only need the basics of classes and how they can be useful. Normally there's a lot of difficult syntax you need to learn, but in Python 3.7 they introduced [`dataclasses`](https://docs.python.org/3/library/dataclasses.html) which is a simple package that makes simple class creation and use easy.

## Anatomy of a class in Python

Before I can explain how to use `dataclasses` in meaningful detail, however, we need to go over what the various bits of a class *are*. Part 1 of this article is a quick primer of what a class looks like and what the various bits of it are called. I am using the built-in Python library `dataclasses` to demonstrate them here which is actually a simplified form of regular classes, but that's the point. These are a *lot* easier than normal classes and I will get to what the syntax means and how to make your own in Part 2. For now, Part 1 is a quick guide to what we call all the bits and pieces that make up a typical class and its usage.

- Classes are defined like functions, except you use the keyword `class` instead of `def` followed by the class name and then a colon. 
    - Class names should always be in `UpperCamelCase` format, with the first letter of each word capitalised and with *no* spaces.

```Python
from dataclasses import dataclass


@dataclass
class HatchBack:
    make: str
    model: str
    weight: float

    def get_summary(self):
        return f'This Hatch back is a {self.make} {self.model} and it weighs {self.weight} kg'


car = HatchBack('Skoda', 'Fabia', 1200.)
summary = car.get_summary()
print(summary)
print(car.make)

```

- The code following the `class` name that is indented explains what the class is and how it behaves, like a function 
    - the whole thing is known as the *definition*
- Any objects created from the class are known as *instances* of that class. 
    - in the code snippet above the variable `car` contains an instance of `HatchBack`.
- If a class has any functions defined in the class definition, these are often referred to as being "on" the class.
- Functions on a class are known as *methods*. 
    - `get_summary` is a method on `HatchBack`.
    - "methods" are called using Python's dot notation, for example `car.get_summary()` in the preceding example.
    - Class methods should always\* include the parameter `self` which refers to the object it*self*, get it?
- You can access, and modify, the variables "on" a class. These are known as "*properties*". 
    - For example, in the preceding example, the class properties are `make`, `model`, and `weight`.
    - Properties are accessed using dot notation.

&gt; \* This isn't *strictly* true as there are a method types that require other parameters instead of `self`, like `classmethod`s and `staticmethod`s, but those are for another time.

- More on `self`. 
    - You **do not** need to provide an argument corresponding to `self`\*\* when calling a method, as shown in the preceding example.
    - Calling `self` "self" is actually a convention thing and you could technically use any name you like (so long as it's consistent within your class).
    - However, *everyone* uses `self` so you may just introduce a lot of unnecessary confusion if you decided to.

&gt; \*\* If you've ever called a method on an object in the past with an argument when you shouldn't have you may have seen `TypeError: HatchBack.get_summary() takes 1 positional argument but 2 were given`, or a variant, before. This is why! `self` counts as a parameter and the argument is automatically supplied by Python at runtime, so if you try to add something in it complains of getting **two** arguments because Python already gave the method one when we weren't looking.

### Decorators and the `@` symbol

At this point I suspect you, as the reader, have a simple question in your mind.

&gt; "Hang on, are you just going to skip over what that `@` means in the example?"

Aha! You got me. Well done for noticing; that actually is an advanced form of Python syntax indicating the application of what's known as a *"decorator"*. Decorators in Python are special functions that can be applied directly to existing functions that change their behaviour at runtime without needing to edit the code. They are functions that accept functions as arguments and return functions as output. They are an example of meta-programming.

What that word salad means is that decorators modify function and class definitions but preserve their names (unless the decorator explicitly affects the name), so you can still call them the same way. For example, you could write a simple decorator called `print_my_args` which prints the arguments supplied to any function that the decorator has been applied to. Its application would look like this.

```python
@print_my_args
def func(a, b, c):
    return a*b + c

```

I hope to cover decorators in depth in a future article, but for now you should know that you only need to be able to recognise them and how to apply them at this level. Creating your own is advanced Python that is well beyond the level in this article series.

### Other Reading

This is the first in a ten-part series on classes in python. For a complete look at the articles in this series, have a look at this overview page: [Getting started with classes in Python](https://developer.ansys.com/blog/getting-started-classes-python)