Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a variable by name from a function in Python [duplicate]

I'm trying the return a given list with a function.

def get_ext(file_type):
    text = ['txt', 'doc']
    audio = ['mp3', 'wav']
    video = ['mp4', 'mkv']
    return ?????

get_ext('audio')  #should return de list ['mp3', 'wav']

Then I'm stuck. This is a simple/short example of a big list of extensions. What is the easiest way to do it?

like image 870
Ludoloco Avatar asked Nov 26 '17 13:11

Ludoloco


2 Answers

In most cases like this, an ordinary dictionary will do the job just fine.

>>> get_ext = {'text': ['txt', 'doc'],
...            'audio': ['mp3', 'wav'],
...            'video': ['mp4', 'mkv']
... }
>>> 
>>> get_ext['video']
['mp4', 'mkv']

If you really want or need a function (for which there can be valid reasons) you have a couple of options. One of the easiest is to assign to the get method of the dictionary. You can even re-assign the name get_ext if you don't have use for the dictionary behind the curtain.

>>> get_ext = get_ext.get
>>> get_ext('video')
['mp4', 'mkv']

This function will return None per default if you enter an unknown key:

>>> x = get_ext('binary')
>>> x is None
True

If you want a KeyError instead for unknown keys, assign to get_ext.__getitem__ instead of get_ext.get.

If you want a custom default-value one approach is to wrap the dictionary inside a function. This example uses an empty list as the default value.

def get_ext(file_type):
    types = {'text': ['txt', 'doc'],
             'audio': ['mp3', 'wav'],
             'video': ['mp4', 'mkv']
    }

    return types.get(file_type, [])

However, @omri_saadon gave the valid remark that the types = ... assignment is performed every function call. Here's what you can do to get around that if this bothers you.

class get_ext(object):
    def __init__(self):
        self.types = {'text': ['txt', 'doc'],
                      'audio': ['mp3', 'wav'],
                      'video': ['mp4', 'mkv']
        }

    def __call__(self, file_type):
        return self.types.get(file_type, [])

get_ext = get_ext()

You can use get_ext like a regular function from here on, because in the end callables are callables. :)

Note that this approach - besides the fact that self.types is only created once - has the considerable advantage that you can still easily change the file types your function recognizes.

>>> get_ext.types['binary'] = ['bin', 'exe']
>>> get_ext('binary')
['bin', 'exe']
like image 153
timgeb Avatar answered Oct 09 '22 02:10

timgeb


If you don't want to define a dictionary as in @timgeb's answer, then you can call local() which gives you a dictionary of the current variables available to use.

def get_ext(file_type):
    text = ['txt', 'doc']
    audio = ['mp3', 'wav']
    video = ['mp4', 'mkv']
    return locals()[file_type]

and a test to show it works:

>>> get_ext("text")
['txt', 'doc']
like image 28
Joe Iddon Avatar answered Oct 09 '22 01:10

Joe Iddon