0

i try to set variables dependend on the type with an switch case statement.

I have a class rule with looks as following:

class rule:

    def __init__(self):
        name = ""
        src = ""

    def setName(self, name):
        self.__name = name

    def getName(self):
        return self.__name
    name = property(getName, setName)

    def setSrc(self, src):
        self.__src = src

    def getSrc(self):
        return self.__src
    src = property(getSrc, setSrc)

and a text file as following

option <type> <value>
option name myname
option src anysrc

I search for the string option and get the secound and third string. as far as good. e.g. (qick and dirty):

with open("file") as f:
    for line in f:
        if line.find('option') != -1:
            type(line.split(' ')[1], line.split(' ')[2])

Now I have write a switch case statement to set variable in object rule.

def type(option, value):
    switcher = {
        "name": rule.name = value,
        "src": rule.src = value,
    }
    switcher.get(option, lambda: "Invalid Option")

But this will not work, I face following:

  File "./read.py", line 112
    "name": rule.name = value,
                      ^
SyntaxError: invalid syntax

I have no idea how to solve this issue or how to solve this by an other way. Any idea how to solve this issue?

Cinux
  • 11
  • 1
  • 1
  • There is no switch statement in Python. You are trying to use a syntax that does not exist. If you want to use a dictionary for control flow like this, you need to write lambda functions, not statements, inside it. – khelwood Feb 18 '18 at 00:52
  • 1
    Possible duplicate of [Replacements for switch statement in Python?](https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python) – khelwood Feb 18 '18 at 00:56
  • Your concrete example you could use `setattr` You'd just have to check separately whether option is in the set of allowed values. – Paul Panzer Feb 18 '18 at 01:01

2 Answers2

0

Python has no switch statement. The common replacement - as you already seem to know - is using a dictionary to dispatch different behaviors. With that being the case however, the syntax you're trying to use simply isn't allowed for dictionaries. Dictionary key values should be expressions. You can work around this by using anonymous functions and setattr. Here's a self-contained example:

>>> class Dummy:
        pass

>>> dummy = Dummy()
>>> dic = {
    'a': lambda: setattr(dummy, 'a', 0),
    'b': lambda: setattr(dummy, 'b', 0)
}
>>> dic.get('a', lambda: print("Invalid Option"))()
>>> dummy.a
0
>>> dic.get('b', lambda: print("Invalid Option"))()
>>> dummy.b
0
>>> dic.get('x', lambda: print("Invalid Option"))()
Invalid Option
>>> 
Christian Dean
  • 22,138
  • 7
  • 54
  • 87
0

you are actually not defining a switch statement up there:

switcher = {
    "name": rule.name = value,
    "src": rule.src = value,
}

This is a dictionary, and the interpreter is complaining about the statements as value there.

You could just reference your methods like this:

def type(option, value):
    switcher = {
        "name": rule.setName,
        "src": rule.setSrc
    } 

    method = switcher.get(option, lambda: "Invalid Option")
    method(rule, value)

Another idea

Here is another aproach. Maybe something like this is helpful:

def type(rule, option, value):
    if hasattr(rule, option):
        setattr(rule, option, value)
    else:
        print("Invalid Option") # Some error handling

Explicitly checking the option name

@PaulPanzer pointed out, that it is maybe in your intention to explicitly check weather options are correct. So here is a more secure version of the typefunction:

def type(rule, option, value):
    if option in ["name", "src"]:
        setattr(rule, option, value)
    else:
        print("Invalid Option") # Some error handling

This implies that you have to change the code in two different places, whenever you extend your file format. But this is a question of how defensive you want to be, how often the rules get extended and how much flexibility you need.

kiecodes
  • 1,642
  • 14
  • 28
  • 2
    `hasattr(rule)`? – Paul Panzer Feb 18 '18 at 01:06
  • 1
    You're missing a second argument for `hasattr`. – Christian Dean Feb 18 '18 at 01:06
  • Correct. Edited that. Thx. – kiecodes Feb 18 '18 at 01:08
  • Syntax aside I wouldn't use `hasattr` here since it is unlikely that you want all attributes settable this way. Why not check against a set with the expected options? – Paul Panzer Feb 18 '18 at 01:12
  • Ah. Good one. If I get this correctly, you mean to check for "setSrc" rather than "src"? – kiecodes Feb 18 '18 at 01:15
  • No, I meant `if option in {'src', 'name'}: ... else: raise ...` Because there is no reason to assume that `rule` wouldn't have other attributes that shouldn't be exposed by this function. – Paul Panzer Feb 18 '18 at 01:25
  • Okay. Gotcha. It implies that you have to change the code in two different places when you want to extend your file format. But I think that is a little bit a question of how defensive you want to be. How often the rules get extended and how much flexibility you need. – kiecodes Feb 18 '18 at 01:36