Вопрос-Ответ

How can I select a variable by (string) name?

Как я могу выбрать переменную по имени (string)?

Я хочу вернуть заранее определенный список из моей функции, основанный на вводе строки.

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

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

Какой самый простой способ это сделать?


О связанной с этим проблеме использования строк для назначения или создания переменных см. в разделе Как мне создавать переменные variable?. Этот вопрос касается их поиска.

Для поиска в существующем объекте (а не в текущих локальных переменных) см. Как получить доступ к атрибуту объекта по заданной строке, соответствующей имени этого атрибута.

Переведено автоматически
Ответ 1

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

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

Если вы действительно хотите или нуждаетесь в функции (для чего могут быть веские причины), у вас есть пара вариантов. Один из самых простых - назначить get методу dictionary . Вы даже можете повторно назначить имя 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's answer, то вы можете вызвать locals(), который выдаст вам dict одну из переменных, доступных в локальной области видимости.

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 со значениями кортежа / списка следующим образом:

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 .

python string