<commit_before># About

Decorators are a feature of the Python language that can modify or register a function.

## How to use them

Decorators are placed just above a function in the code like so:

```python
@decorator
def function():
    pass
```

Some decorators take arguments:

```python
@decorator2(name="Bob")
def function2():
    pass
```

If a decorator takes any arguments, but you don't wish to pass any, you must still call it with parentheses for the decorator to work:

```python
@decorator3()
def function3():
    pass
```

Decorators are just syntactic sugar.
An alternative way of doing the same as the above three examples is using higher-order functions:
```python
def function():
    pass

function = decorator(function)


def function2():
    pass

function2 = decorator2(name="Bob")(function2)


def function3():
    pass

function3 = decorator3()(function3)
```

## How to write them

As said before, decorators can modify or register a function.
The simplest decorator however, does absolutely nothing.

Decorators are functions which return functions.
They take one argument - the function which they have been added to.
They also return one thing - the function which will be run by the program.
This is usually either the function they were added to or a slightly modified version of that function, but it does not have to be - it can be any function whatsoever.

The simplest decorator - one that does nothing - can be written as follows:
```python
def do_nothing(function):
    return function
```
```python
def function4a():
    return 4

@do_nothing
def function4b():
    return 4
```
```python
>>>function4a()
4
>>>function4b()
4
```
As you can see, both functions do the same thing, and when the decorator is added nothing changes.

A decorator that registers a function could be written as follows:
```python
functions = []

def register_function(function):
    functions.append(function)
    return function
```
```python
>>>functions
[]
```
```python
@register_function
def function5():
    return 5
```
```python
>>>functions
[<function function5 at 0x000001CA840AA700>]
>>>function5()
5
```
As you can see, adding the decorator to the function adds the function into the list.
It is important to note that this happens when the function is declared, not when it is called.<commit_msg>First decorator modifying the original function<commit_after># About

Decorators are a feature of the Python language that can modify or register a function.

## How to use them

Decorators are placed just above a function in the code like so:

```python
@decorator
def function():
    pass
```

Some decorators take arguments:

```python
@decorator2(name="Bob")
def function2():
    pass
```

If a decorator takes any arguments, but you don't wish to pass any, you must still call it with parentheses for the decorator to work:

```python
@decorator3()
def function3():
    pass
```

Decorators are just syntactic sugar.
An alternative way of doing the same as the above three examples is using higher-order functions:
```python
def function():
    pass

function = decorator(function)


def function2():
    pass

function2 = decorator2(name="Bob")(function2)


def function3():
    pass

function3 = decorator3()(function3)
```

## How to write them

As said before, decorators can modify or register a function.
The simplest decorator however, does absolutely nothing.

Decorators are functions which return functions.
They take one argument - the function which they have been added to.
They also return one thing - the function which will be run by the program.
This is usually either the function they were added to or a slightly modified version of that function, but it does not have to be - it can be any function whatsoever.

The simplest decorator - one that does nothing - can be written as follows:
```python
def do_nothing(function):
    return function
```
```python
def function4a():
    return 4

@do_nothing
def function4b():
    return 4
```
```python
>>>function4a()
4
>>>function4b()
4
```
As you can see, both functions do the same thing, and when the decorator is added nothing changes.

A decorator that registers a function could be written as follows:
```python
functions = []

def register_function(function):
    functions.append(function)
    return function
```
```python
>>>functions
[]
```
```python
@register_function
def function5():
    return 5
```
```python
>>>functions
[<function function5 at 0x000001CA840AA700>]
>>>function5()
5
```
As you can see, adding the decorator to the function adds the function into the list.
It is important to note that this happens when the function is declared, not when it is called.

Many decorators you write will change what is run when the function is called.
These will need to return a different function to the one passed.
This different function is written inside the decorator's function.

This decorator doubles the result of the function:
```python
def double(function):
    def wrapper():
        function_result = function()
        doubled = function_result * 2
        return doubled
    return wrapper
```
```python
def function6a():
    return 6

@double
def function6b():
    return 6
```
```python
>>>function6a()
6
>>>function6b()
12
```
As you can see the decorator modifies the result of the function.
{'fraction_non_alphanumeric': 0.08537044001504325, 'fraction_numerical': 0.016171493042497178, 'mean_word_length': 4.324324324324325, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '332524', 'n_tokens_mistral': 1525, 'n_tokens_neox': 1414, 'n_words': 720}