Возвращает переменную по имени из функции в Python

Я пытаюсь вернуть данный список с помощью функции.

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

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

Тогда я застрял. Это простой/короткий пример большого списка расширений. Что это самый простой способ сделать это?

Ответ 1

В большинстве случаев обычный словарь отлично справится с задачей.

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

Если вам действительно нужна или нужна функция (для которой могут быть веские причины), у вас есть несколько вариантов. Одним из самых простых является назначение метода get словаря. Вы даже можете назначить имя get_ext, если у вас нет словаря для занавеса.

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

Эта функция вернет None по умолчанию, если вы вводите неизвестный ключ:

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

Если вы хотите использовать KeyError вместо неизвестных ключей, назначьте get_ext.__getitem__ вместо get_ext.get.

Если вы хотите использовать настраиваемое значение по умолчанию, один из них заключается в том, чтобы обернуть словарь внутри функции. В этом примере в качестве значения по умолчанию используется пустой список.

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

    return types.get(file_type, [])

Однако @omri_saadon дал правильное замечание о том, что назначение types = ... выполняется при каждом вызове функции. Вот что вы можете сделать, чтобы обойти это, если это вас беспокоит.

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()

Вы можете использовать get_ext как регулярную функцию здесь, потому что в конце вызывающие вызовы являются вызывающими.:)

Обратите внимание, что этот подход, помимо того, что self.types создается только один раз, имеет значительное преимущество в том, что вы все еще можете легко изменять типы файлов, распознаваемые вашей функцией.

>>> get_ext.types['binary'] = ['bin', 'exe']
>>> get_ext('binary')
['bin', 'exe']

Ответ 2

Если вы не хотите определять dictionary, как в @timgeb answer, вы можете позвонить local(), который дает вам dictionary текущий variables, который можно использовать.

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

и тест, чтобы показать, что он работает:

>>> get_ext("text")
['txt', 'doc']

Ответ 3

Вы можете легко использовать dict с параметрами tuple/list, например:

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


print(get_ext('audio'))

Ответ 4

Использовать словарь:

def get_ext(file_type):
    d = {'text' : ['txt', 'doc'],
         'audio' : ['mp3', 'wav'],
         'video' : ['mp4', 'mkv']}
    try:
        return d[file_type]
    except KeyError:
        return []

get_ext('audio') # ['mp3', 'wav']

возвращает пустой список в случае, если ключ не существует. как это самый простой ответ, который пришел мне на ум, для лучшего ответа см. ответ @timgeb.

Ответ 5

В соответствии с ответом от @timgeb я бы использовал словарь, но если вы много посещаете, заботитесь о скорости и не хотите определять класс, вы можете использовать кеширование.

from functools import lru_cache

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

@lru_cache(maxsize=3, typed=False)
def get_ext_cached(file_type):
    d = {'text': ['txt', 'doc'],
         'audio': ['mp3', 'wav'],
         'video': ['mp4', 'mkv']}
    return d[file_type]

from timeit import timeit

# non cached
print(timeit(stmt='get_ext("text")', globals={'get_ext': get_ext}))
# 0.48447531609922706 on my machine

# cached
print(timeit(stmt='get_ext("text")', globals={'get_ext': get_ext_cached}))
# 0.11434909792297276

Хотя для этого конкретного случая он, вероятно, будет излишним, и вы можете просто позвонить непосредственно в словарь (кеш только строит собственный словарь и делает именно это), вы можете использовать его в будущем для любых чистых функций, которые эффективно вычисляются.

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

# 0.05016115184298542
print(timeit(stmt="d['text']",
             globals={'d':d,'c':c}))