繁体   English   中英

如何通过(字符串)名称 select 变量?

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

我想根据字符串输入从我的 function 返回一个预先确定的列表。

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']

最简单的方法是什么?


关于尝试使用字符串赋值或创建变量的相关问题,请参见如何创建变量变量? . 这个问题是关于查找它们的。

在大多数情况下,普通的字典就可以完成这项工作。

>>> 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']

如果您不@timgeb's answer那样定义dictionary ,那么您可以调用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']

您可以轻松地将 dict 与元组/列表值一起使用,如下所示:

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


print(get_ext('audio'))

使用字典:

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 答案。

根据@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

尽管对于这种特殊情况,它可能有点矫枉过正,您可以直接在字典上调用 get (缓存只是构建自己的字典并做到这一点),您将来可以将其用于任何有效的计算查找的纯函数。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM