Make object subscriptable python

Python TypeError: ‘int’ object is not subscriptable

In Python, we use Integers to store the whole numbers, and it is not a subscriptable object. If you treat an integer like a subscriptable object, the Python interpreter will raise TypeError: ‘int’ object is not subscriptable.

In this tutorial, we will learn what ‘int’ object is is not subscriptable error means and how to resolve this TypeError in your program with examples.

What is Subscriptable in Python?

Subscriptable” means that you’re trying to access an element of the object. The elements are usually accessed using indexing since it is the same as a mathematical notation that uses actual subscripts.

How do you make an object Subscriptable?

In Python, any objects that implement the __getitem__ method in the class definition are called subscriptable objects, and by using the __getitem__ method, we can access the elements of the object.

For example, strings, lists, dictionaries, tuples are all subscriptable objects. We can retrieve the items from these objects using indexing.

How to Fix TypeError: ‘int’ object is not subscriptable?

Let us take a small example to read the birth date from the user and slice the day, months and year values into separate lines.

birth_date = int(input("Please enter your birthdate in the format of (mmddyyyy) ")) birth_month = birth_date[0:2] birth_day = birth_date[2:4] birth_year = birth_date[4:8] print("Birth Month:", birth_month) print("Birth Day:", birth_day) print("Birth Year:", birth_year) 

If you look at the above program, we are reading the user birth date as an input parameter in the mmddyy format.

Читайте также:  Disconnect failed ticket authorization css v34

Then to retrieve the values of the day, month and year from the user input, we use slicing and store it into a variable.

When we run the code, Python will raise a TypeError: ‘int’ object is not subscriptable.

Please enter your birthdate in the format of (mmddyyyy) 01302004 Traceback (most recent call last): File "C:\Personal\IJS\Code\main.py", line 3, in birth_month = birth_date[0:2] TypeError: 'int' object is not subscriptable

Solution

In our example, we are reading the birth date as input from the user and the value is converted to an integer.

The integer values cannot be accessed using slicing or indexing, and if we do that, we get the TypeError.

To solve this issue, we can remove the int() conversion while reading the input from the string. So now the birth_date will be of type string, and we can use slicing or indexing on the string variable.

Let’s correct our example and run the code.

birth_date = input("Please enter your birthdate in the format of (mmddyyyy) ") birth_month = birth_date[0:2] birth_day = birth_date[2:4] birth_year = birth_date[4:8] print("Birth Month:", birth_month) print("Birth Day:", birth_day) print("Birth Year:", birth_year) 
Please enter your birthdate in the format of (mmddyyyy) 01302004 Birth Month: 01 Birth Day: 30 Birth Year: 2004

The code runs successfully since the int() conversion is removed from the code, and slicing works perfectly on the string object to extract a day, month and year.

Conclusion

The TypeError: ‘int’ object is not subscriptable error occurs if we try to index or slice the integer as if it is a subscriptable object like list, dict, or string objects.

The issue can be resolved by removing any indexing or slicing to access the values of the integer object. If you still need to perform indexing or slicing on integer objects, you need to first convert that into strings or lists and then perform this operation.

Источник

Sohliloquies

d.get(k) defaults to None if a key is not found, whereas d[k] throws a KeyError . When the key is present, though, these two ways of getting data are more or less equivalent.

The same goes for nested dictionaries:

d =  'eggs':  'breakfast': 'maybe', 'lunch': 'i guess', 'dinner': 'nah' >, 'sausage':  'breakfast': 'deffo', 'lunch': 'yee', 'dinner': 'why not' >, 'sushi':  'breakfast': 'wtf', 'lunch': 'erryday', 'dinner': 'sometimes' > > d['eggs']['lunch'] # this works d.get('sushi').get('breakfast') # so does this d.get('sausage')['breakfast'] # this too -- but it's mega ugly 

The particularly astute reader might already have sense of where this is going.

I’m writing a module to manage and expose a JSON config file to a Python app, and internally it represents the config using native Python data types. To the rest of the world, access is mediated via a .get call:

class Config: . # load config file data, etc def get(self, *args, **kwargs): return self.config.get(*args, **kwargs) # config query singleton -- prevents unnecessarily re-reading conf file _config = Config() get = _config.get 

The idea is that other code, after import config , can call config.get and interface with the module similarly to how you’d deal with a plain dictionary. But here’s the catch: the config data includes nested dictionaries. Accessing these would involve either chaining .get calls or mixing .get and subscript notation — either of which would lead to ugly code.

What to do? There are a couple options here.

The simple, easy option would be to find a different way of exposing the config file.

The other option would be to find a way to make the entire module subscriptable, and to make subscripting it return the correct results.

I’m not really opposed to either option, but I know which one sounds more fun.

Internally, Python handles subscripting by calling an instance’s __getitem__ method. But just defining a function named __getitem__ at module level won’t work:

user@development:/tmp/tests$ cat a.py import random def __getitem__(self, key): return random.choice(("o shit lol", "whaa", "no way", "lmfao")) user@development:/tmp/tests$ cat b.py import a for _ in range(10): print(a[_]) user@development:/tmp/tests$ python3 b.py Traceback (most recent call last): File "b.py", line 4, in print(a[_]) TypeError: 'module' object is not subscriptable

What’s going wrong here? That’s a simple question with a hard answer. The answer also varies somewhat depending on how far into the weeds of Python’s object-oriented internals we want to wade. A few explanations, tuned to varying comfort levels:

Python doesn’t make it easy for us to override ‘magic’ functions like __getitem__ at the module level, for that way madness lies.

Python wants __getitem__ to be a bound method, not just a function.

Specifically, __getitem__ must be bound to the object whose scope it’s in (i.e. this module), something that there’s no real pretty way of doing from inside the module body.

This last one explains why the following fails:

user@development:/tmp/tests$ cat a.py import random class Foo(): def __getitem__(self, key): return random.choice(("o shit lol", "whaa", "no way", "lmfao")) _foo = Foo() __getitem__ = _foo.__getitem__ user@development:/tmp/tests$ cat b.py import a for _ in range(10): print(a[_]) user@development:/tmp/tests$ python3 b.py Traceback (most recent call last): File "b.py", line 4, in print(a[_]) TypeError: 'module' object is not subscriptable

It’s starting to look like our goal of making the module subscriptable would require some deep, dark wizardry, maybe even hooking on module import or something equally perverse. The good news is that we can contain the perversity to a reasonably small area. The solution is to have the module overwrite its own entry in the sys.modules registry, replacing itself with a tailor-made object possessing the desired bound method. Check it out:

user@development:/tmp/tests$ cat a.py import random import sys import types class Foo(types.ModuleType): def __getitem__(self, key): return random.choice(("o shit lol", "whaa", "no way", "lmfao")) sys.modules[__name__] = Foo("a") user@development:/tmp/tests$ cat b.py import a for _ in range(10): print(a[_]) user@development:/tmp/tests$ python3 b.py no way lmfao no way o shit lol no way whaa o shit lol whaa whaa o shit lol

And there you have it! We use __name__ to guarantee we’re indexing into sys.modules at the right place. We pass the name of the module («a») to the object constructor, which was inherited from types.ModuleType and expects a module name.

So there you have it: that’s how to make a module subscriptable. Similar tricks would probably work for making a module e.g. callable, or really giving it any combination of properties implemented through __magic__ functions.

Источник

Make object subscriptable python

Last updated: Jan 31, 2023
Reading time · 2 min

banner

# TypeError: ‘bool’ object is not subscriptable in Python

The Python «TypeError: ‘bool’ object is not subscriptable» occurs when we use square brackets to try to access a bool object at a specific index or specific key.

To solve the error, track down where the value got assigned a boolean and correct the assignment.

typeerror bool object is not subscriptable

Here are 2 examples of how the error occurs.

Copied!
my_bool = True # ⛔️ TypeError: 'bool' object is not subscriptable print(my_bool[0]) # ⛔️ TypeError: 'bool' object is not subscriptable print(my_bool['name'])

Boolean objects are not subscriptable. In other words, we can’t use square brackets to access a boolean at a specific index or to try to access a boolean’s key.

# Track down where the variable got assigned a boolean value

You have to track down where the variable got assigned a boolean, and correct the assignment to a value that is subscriptable, e.g. a string, list or a dictionary.

Make sure you haven’t reassigned a subscriptable value to a boolean somewhere in your code.

Copied!
my_list = ['a', 'b', 'c'] # 👇️ reassigned to boolean by mistake my_list = False # ⛔️ TypeError: 'bool' object is not subscriptable print(my_list[0])

We initially set the my_list variable to a list, but then we reassigned it to a boolean which caused the error.

You can try to remove the square brackets accessor if the value is intended to be a boolean.

If you have a missing comma between a boolean value and a list, make sure to place the comma between the two values.

If you meant to declare a dictionary and access a key, use curly braces to wrap the key-value pairs.

Copied!
my_dict = 'id': 1, 'name': 'Bobby Hadz'> print(my_dict['id']) # 👉️ 1 print(my_dict['name']) # 👉️ Bobby Hadz

If the variable is meant to store a string, wrap it in quotes.

Copied!
my_str = 'bobbyhadz.com' print(my_str[0]) # 👉️ b print(my_str[1]) # 👉️ o print(my_str[0:5]) # 👉️ bobby

The error means that we are using square brackets to access a key in a specific object or to access a specific index, however, the object doesn’t support this functionality.

Python indexes are zero-based, so the first character in a string has an index of 0 , and the last character has an index of -1 or len(a_string) — 1 .

# Only use square brackets to access subscriptable objects

You should only use square brackets to access subscriptable objects.

The subscriptable objects in Python are:

All other objects have to be converted to a subscriptable object by using the list(), tuple(), dict() or str() classes to be able to use bracket notation.

Subscriptable objects implement the __getitem__ method whereas non-subscriptable objects do not.

Copied!
a_list = [2, 4, 6, 8] # 👇️ print(a_list.__getitem__)

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.

Источник

Оцените статью