lettura simple

The __getitem__() Method in Python

The `__getitem__()` method in Python is a special or "magic" method that handles both indexing and slicing.

obj.__getitem__(index)

This method is automatically invoked whenever you try to access an element of an object using square brackets [ ].

In Python, the [ ] operator is used to access elements in a collection, such as lists, tuples, or dictionaries, and it triggers the special __getitem__() method of the object on which it's used.

For instance, let's define a list:

my_list = ["a", "b", "c", "d", "e"]

Now, access the list by specifying the position of the element you want to retrieve within the square brackets.

print(my_list[0])

a

When you write `my_list[0]`, Python is actually calling the `__getitem__()` method on the list `my_list`, passing `0` as the argument.

Keep in mind that in Python, the index of elements starts at zero. So, the first element is at position zero, the second is at position one, and so on.
an example of a string

You can achieve the same result by directly calling the `__getitem__()` method on the list.

Again, you need to specify the position of the element you want to access as the argument inside the parentheses.

print(my_list.__getitem__(0))

a

To access the second element of the list, you would specify position 1.

print(my_list.__getitem__(1))

b

The __getitem__() method is also invoked when dealing with iterable objects.

For example, let’s turn the list into an iterable object:

obj = my_list.__iter__()

Then, use the next function to access each element sequentially:

print(next(obj))

The next function automatically calls the __getitem__(0) method and returns the first element of `my_list`.

a

Now use the next function again.

print(next(obj))

The next function automatically calls the __getitem__(1) method and returns the second element of `my_list`.

b

And so forth.

Defining a Class That Uses the `__getitem__()` Method

The __getitem__() method also allows you to define a class that behaves like a list, dictionary, or any other iterable object.

This enables you to create custom data structures by overloading the `[ ]` operator.

What is overloading? Overloading allows you to modify the behavior of an object's methods within a class. For instance, instead of simply reading and returning an element, you can perform operations or calculations on the element before returning it.

A Practical Example

Imagine you want to create a class that represents a simple list of numbers but with slightly different behavior.

Suppose you want to calculate the square of a number every time you access an element.

class MyList:
    def __init__(self, numbers):
        self.numbers = numbers

    def __getitem__(self, index):
        # Return the square of the element at the specified index
        return self.numbers[index] ** 2

In the `MyList` class, the `__getitem__()` method has been overridden to return the square of the number at the specified index.

When you access an element, Python calls `__getitem__(0)` and returns its square.

For example, create an instance of `MyList`:

my_list = MyList([1, 2, 3, 4, 5])

Now access the elements as if it were a normal list:

print(my_list[1])

The result is 4 because the second element of the list is 2, and its square is 22 = 4.

4

Example 2

Now, let's consider a slightly more complex example.

Imagine you want to create a case-insensitive dictionary that ignores the case (uppercase or lowercase) of the keys:

class CaseInsensitiveDict:
    def __init__(self, data):
        self.data = {key.lower(): value for key, value in data.items()}

    def __getitem__(self, key):
        # Convert the key to lowercase before looking it up in the dictionary
        return self.data[key.lower()]

In this class, the `__getitem__()` method always converts the key to lowercase before searching for it in the internal dictionary.

For example, create an instance of `CaseInsensitiveDict`:

dictionary = CaseInsensitiveDict({'Name': 'Alice', 'Age': 30})

Now you can access the keys without worrying about case sensitivity.

For instance, both `dictionary['Name']` and `dictionary['name']` will return the same value.

print(dictionary['name'])

'Alice'

You can retrieve the same value even if you type the key in all uppercase letters.

print(dictionary['NAME'])

'Alice'

The result is always the same.

In this way, you've created a dictionary that treats keys as case-insensitive.

Note: As you can see from this example, the index of an object isn't always an integer. In the case of dictionaries, the index is actually the key.

This demonstrates how the __getitem__() method allows you to customize access to elements within a collection in your class, enabling you to create complex and specific behaviors for your objects.




Report a mistake or post a question




FacebookTwitterLinkedinLinkedin