python dictionary.get()方法使用默认值抛出异常,即使它不应该执行

9rygscc1  于 2023-01-03  发布在  Python
关注(0)|答案(3)|浏览(314)

我有一个字典,我想从使用. get()方法检索一些值,如果键不存在,应该执行一个默认函数,返回正确的值,但它应该只在键不存在时执行。
我试着删除默认值,它起作用了,那么为什么函数即使不被使用也会被执行呢?
SQL查询将不返回任何值,因为它只包含字典中尚未包含的值

def get_port():

    def default():
        cursor.execute("SELECT port FROM table WHERE server=%s LIMIT 1",(server_name,))
        return cursor.fetchone()[0]

    port = {
        'server1': 2222,
        'server2': 2223,
        'server3': 2224
        }
    #print(port.get(server_name)) << Works
    return port.get(server_name, default())

错误:
返回游标。fetchone()[0]类型错误:"NoneType"对象不可订阅
我希望默认函数仅在键不存在时执行。

bpsygsoo

bpsygsoo1#

get的默认值需要构建/评估,其问题在于即使不需要代码,也会执行代码,这会降低代码速度,或者在您的情况下触发不必要的错误。
另一种办法是:

port.get(server_name) or default()

如果get因为找不到键而返回None,则or default()被激活,但是如果get返回了一些东西,则它短路,并且不调用default()
(this如果get返回空字符串、零或任何“falsy”值,则会失败,但在您的情况下-服务器名称-我认为不会发生这种情况)
另一种选择(在这里可能有些过分)是使用collections.defaultdict对象

port = collections.defaultdict(default)
port.update({
        'server1': 2222,
        'server2': 2223,
        'server3': 2224
        })

然后,每次用未知键调用port[server]都会调用default函数,并将结果存储在字典中,将port设置为全局或持久,这样就创建了一个很好的缓存:下一次取出相同的值时,缺省值已经在字典中。

hpcdzsge

hpcdzsge2#

你正在调用这个函数,所以它确实被执行了(default() vs. default)(即使你没有调用它,比如.get(..., default),你也只会得到函数对象,这不符合你的目的)。
如果你只想在键不存在的时候调用它,你需要稍微详细一点--在这一点上,它值得像这样重构:

ports = {
    "server1": 2222,
    "server2": 2223,
    "server3": 2224,
}

def get_port(server_name):
    port = ports.get(server_name)
    if not port:
        cursor.execute(
            "SELECT port FROM table WHERE server=%s LIMIT 1",
            (server_name,),
        )
        port = cursor.fetchone()[0]
    return port
2cmtqfgy

2cmtqfgy3#

上一个答案将为您带来当前问题的解决方案。
default()首先被评估。
我想包含一些更多的信息来帮助你理解正在发生的事情。这个问题可能看起来很天真,但它涉及到Python(实际上是任何编程语言)的基本方面。希望这会引起一些读者的兴趣。
第一个被误解的方面与eager evaluation有关,Python是一个热切的评估者。
然后,阅读get()方法本身--它返回一个 value,这可能是一个函数,因为函数在Python中是first class objects

相关问题