Возвращает переменную по имени из функции в 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}))