python中对象调用函数的切换实现

Switch Implementation of Object calling function in python

我正在尝试在 Python 中实现字典中的切换。但是当我调用方法时
chooices.get(x, "Ther is no program") 它调用语句中的所有函数而不是调用 x 函数。

我已经阅读了这个实现 Replacements for switch statement in Python?

但这对我的情况没有帮助,因为我的函数有打印语句

主文件包含代码

from  Day1.Day1 import Day1
from Day2.TipCalculator import TipCalculator


def choose():
    print("Choose From the following Program:\n")
    day1 = Day1()
    day1.day1()

    day2 = TipCalculator()
    day2.day2()


    x = int(input());


    chooices={
        1: day1.program1(),
        2: day2.program1(),

    }
    chooices.get(x, "Ther is no program")    

choose()

第 1 天 Class 包含代码

class Day1:

    def day1(self):
        print('1. Band name Generator\n')

    def program1(self):
        print('Welcome to Band Name Generator.\n')
        cityName=input('What\'s is the name of city you grew up?\n')
        petName = input('What\'s your pet\'s name?\n')
        print('Your Band Name could be : '+cityName+" "+petName)

Class 小费计算器代码

class TipCalculator:
    def day2(self):
        print("2. Tip Calculator For  Bill.\n")

    def program1(self):
        print('Welcome to tip calculator.\n')

我只需要实现像switch一样调用请求程序的switch语句。我知道它可能通过 If-else 但字典映射似乎是 switch

的好选择

概述:解释器为子函数使用的非本地变量创建一个闭包。在此示例中,子变量的值为 22 并存储在闭包单元格中。

  def parent(arg_1, arg_2):
  value=22
  my_dict = {'chocolate':'yummy'}
  def child():
    print(2*value)
    print(my['chocolate'])
    print(arg_1 + arg_2)
   return child

  new_function=parent(3,4)

  print(cell.cell_contents for cell in new_function.__closure__])

如果您没有很多变体,可以使用开关的辅助函数简化 if/elif/else 语句。这只是语法糖,但对于小值集可能就足够了。

def switch(v): yield lambda *c: v in c

用法示例:

x = int(input())
for case in switch(x):
    if   case(1): day1.program1()
    elif case(2): day2.program1()
    else:         print("there is no program")

支持同一方法调用的多个值:

x = int(input())
for case in switch(x):
    if   case(1,5):   day1.program1()
    elif case(2,3,4): day2.program1()
    else:             print("there is no program")

你也可以用更像 C 的风格来使用它

x = int(input())
for case in switch(x):

    if case(1,5):   
       day1.program1()
       break

    if case(2,3,4): 
       day2.program1()
       break
else:
    print("there is no program")

如果你有 python 3.10 或更高版本,一个适当的开关模拟被实现,称为 "match",它应该可以很好地替换其他答案可能具有的任何嵌套 if 语句。

如果你没有 3.10,并且你可以接受一个非常 hacky 的解决方案,我的想法来自 withhacks (specifically from AnonymousBlocksInPython)。我最近在 python 中创建了我自己的 switch 语句版本,它的行为更像我在 C# 中的习惯。您可以根据需要扩展它,超越单行参数或赋值。

它使用上下文管理器,因此您可以将每个案例都视为带有缩进和所有内容的自己的代码块。如果 case 值与 switch 值不匹配,它永远不会进入 case,因此对于非常耗费系统的代码,您可以确定它不是 运行 不需要的代码。

import sys


class CaseReturn(Exception):pass
class Case:
    def __init__(self, caseVal): self._caseVal_ = caseVal
    def _trace_(self,frame,event,arg): raise CaseReturn
    def __enter__(self):
        if self._caseVal_ == Switch._singleton_._switch_: return
        sys.settrace(lambda *args, **keys: None)
        sys._getframe(1).f_trace= self._trace_
    def __exit__(self,ExType,ExVal,ExTrace): 
        if ExType is None: raise CaseReturn
        return ExType is CaseReturn 


class Switch:
    _singleton_:'Switch' = None
    def __init__(self, switchVal,Default=None): self._switch_ = switchVal
    def __enter__(self):Switch._singleton_ = self
    def __exit__(self,ExType,ExVal,ExTrace): 
        Switch._singleton_ = None
        return ExType is CaseReturn


with Switch(2):
    with Case(1): 
        print('This should not make it')
    with Case(2):
        print('I made it')
    with Case(3):
        print('This should never be called')

您只需将 caseVal 更改为列表并执行 if Switch._singleton_._switch_ in self._caseVal_:

即可轻松扩展它以检查多个案例

需要注意的是,您不能像这样将 Case 语句设为一行:

Case(0): print('I am one line')

不管怎样,那都行不通,在这种情况下最终会调用代码。 我希望这对您或任何正在搜索自定义 Switch 语句的人有用!