Python switch-case 意外执行了所有 case

Python switch-case unexpectedly executing all cases

原文post(下方edit/update:)

我正在尝试在 Python 中创建一个 switch-case 函数以避免非常长的 if:elseif:elseif:elseif...else 语句(运行ning 3.7 所以没有3.10 的匹配案例语句)。所以,我正在玩这个字典查找(为了这个例子的目的,它被故意保持简短)。

我已经在程序的其他地方定义了一个类似的函数,它按预期工作。但是,新的 switch-case 函数应该调用其他函数以响应提供的输入(我只是 returns 一个值的其他查找)。奇怪的是,它会执行每种情况,而不仅仅是需要的情况。而且,我不明白为什么。

# switcher.py
# optional cli args: ipaddress, port

def config_updater(k, v):
    print(f'config_update(k,v): {k, v}')  # Sanity check
    switcher = {
        'ipaddress': update_ip(v),
        'port': update_port(v)
    }

    return switcher.get(k)


def update_ip(a):
    global host_ip
    host_ip = a
    print(f'update_ip: host_ip updated to {a}')


def update_port(b):
    global host_port
    host_port = b
    print(f'update_port: host_port updated to {b}')

#
# Code for command line argparse functionality goes here
# Essentially, arguments (ipaddress, port) can be optionally added at command line
#

args = parser.parse_args()
dargs = vars(args)  # Creates a dictionary of command line arguments and their values

# Setting default values if no arguments added at command line
global host_ip, host_port
host_ip = 'localhost'
host_port = 4840
i = 1  # For loop counter

for field, value in dargs.items():
    print(f'\n\nFor loop iteration: {i}\n')  # Sanity check
    i += 1
    print(f'Printing current field-value pair: {field}, {value}\n')  # Sanity check
    if value is not None:
        config_updater(field, value)

print(f'\n\nPrinting final statement:')
print(f'IP address: {host_ip}')
print(f'Port: {host_port}')

现在,当这是 运行 时:

$ python3 switcher.py -ip 192.168.0.28 -p 2228

我得到以下输出,运行s update_ip 和 update_port 用于两个参数,而不仅仅是它们各自的查找。

For loop iteration: 1

Printing current field-value pair: ipaddress, 192.168.0.28

config_update(k,v): ('ipaddress', '192.168.0.28')
update_ip: host_ip updated to 192.168.0.28
update_port: host_port updated to 192.168.0.28


For loop iteration: 2

Printing current field-value pair: port, 2228

config_update(k,v): ('port', '2228')
update_ip: host_ip updated to 2228
update_port: host_port updated to 2228


Printing final statement:
IP address: 2228
Port: 2228

澄清一下,我希望输出为:

For loop iteration: 1

Printing current field-value pair: ipaddress, 192.168.0.28

config_update(k,v): ('ipaddress', '192.168.0.28')
update_ip: host_ip updated to 192.168.0.28


For loop iteration: 2

Printing current field-value pair: port, 2228

config_update(k,v): ('port', '2228')
update_port: host_port updated to 2228


Printing final statement:
IP address: 192.168.0.28
Port: 2228

我是否从根本上误解了如何使用这些查找来调用其他函数?

编辑(基于标记的答案和评论):

我修改后的代码继续使用字典查找 - 与原始问题内联 - 但已进行调整以使用已经可用的全局 argsparser 变量,现在看起来像这样:

# switcher.py
# optional cli args: ipaddress, port

def get_default_config(field):
    switcher = {
        'ipaddress': set_default_ip,
        'port': set_default_port
    }
    func_to_use = switcher.get(field)
    if func_to_use:
        return func_to_use()


def set_default_ip():
    args.ipaddress = 'localhost'
    print(f'update_ip: host_ip updated to {args.ipaddress}')


def set_default_port():
    args.port = 4840
    print(f'update_port: host_port updated to {args.port}')

#
# Code for command line argparse functionality goes here
# Essentially, arguments (ipaddress, port) can be optionally added at command line
#

args = parser.parse_args()
dargs = vars(args)

for field, value in dargs.items():
    if value is None:
        get_default_config(field)

print('\n\n')
print(f'IP address set to: {args.ipaddress}')
print(f'Port set to: {args.port}')

感谢所有做出贡献的人!

当你像这样定义字典时

switcher = {
        'ipaddress': update_ip(v),
        'port': update_port(v)
    }

调用 函数并将这些函数的返回值分配给字典的那个键。

相反,您希望将函数本身分配为字典中的值,并在知道需要哪个时稍后调用它们。

switcher = {
        'ipaddress': update_ip,
        'port': update_port
    }
func_to_use = switcher.get(k)
if func_to_use:
    return func_to_use(v)