2

I want to define a dictionary inside a function. How I can define that dictionary only one time and on the function creation time. I'm trying to prevent dictionary creation on each function call. currently I define a global dictionary and use that inside the function, but is there another solution?

media_types = {
    1: 'New Video',
    2: 'New Image',
    3: 'New File',
}

def get_media_type(t):
    return media_types.get(t, None)
Jahan
  • 363
  • 6
  • 16
  • 1
    Your solution is pythonic. Is there a reason you want to avoid the dictionary created globally? – vekerdyb Jul 21 '19 at 07:46
  • 1
    Make it the default value of a parameter? But that's risky for other reasons: https://stackoverflow.com/q/1132941/3001761. – jonrsharpe Jul 21 '19 at 07:47
  • @vekerdyb I want to put all the related code in one place for better readability and to prevent unwanted changes to the global variable. – Jahan Jul 21 '19 at 07:49
  • @jonrsharpe Yes, I think this is a good solution for my intentions. Do you think there will be a problem if I don't modify the dictionary? – Jahan Jul 21 '19 at 07:54

2 Answers2

6

You can do this by using closures in python

def get_media_type():
    media_types = {
        1: 'New Video',
        2: 'New Image',
        3: 'New File',
    }
    def media_type_wrapper(t):
        return media_types.get(t, None)
    return media_type_wrapper


get_media_type = get_media_type()

For more info on closures in python https://www.programiz.com/python-programming/closure

Umesh Chaudhary
  • 391
  • 1
  • 6
  • why isn't the `dict` created every time `get_media_type` is called? – Neb Jul 21 '19 at 09:13
  • 1
    @Neb Because the function `get_media_type` you see defined above is actually called only once! after that, calling `get_media_type` will actually call the inner `media_type_wrapper`. Beautiful solution! +1 – Tomerikoo Jul 21 '19 at 09:14
2

You could create it as a function's attribute, and to create only once use a try/except:

def get_media_type(t):
    try:
        media_types = get_media_type.media_types
    except AttributeError:
        get_media_type.media_types = {
                            1: 'New Video',
                            2: 'New Image',
                            3: 'New File',
                            }
        media_types = get_media_type.media_types

    return media_types.get(t, None)

This way, the Exception will be thrown only at the first time the function is called, and thus the dictionary will be defined. All subsequent calls to the function will not raise the exception and the dictionary will be used.


But, as you can see this is a bit messy and your current solution is readable and does the job

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61