Python切换功能

时间:2015-08-27 11:54:50

标签: python switch-statement

我一直在尝试使用if构建的简单切换功能编写简单的端口扫描程序。我已经在这里搜索了一个关于如何使开关功能像C ++或similli一样可用的正确解决方案。我发现这个问题已经在这里讨论了Replacements for switch statement in Python?,我尝试了一些这样的方法,但到目前为止还没有任何运气使它运行正常。无论我从链接中选择哪种方法,我总是会在第二个开关盒上出现语法错误,如下所示:

  File "/home/h4v0kkx0008c/Desktop/Sources/setup/PortScannerV1.py", line 44
if case(2):
          ^
SyntaxError: invalid syntax

这可能是什么问题?

这是我到目前为止写的完整代码:

from socket import *
import time, socket, os, sys, string, argparse, logging, math

n = raw_input("Choose Port range: \n(1)Standard Ports: 0 - 1025\n(2)Middle Range: 1025 - 5000\n(3)Higher Range: 5000 - 49151\n(4)Highest Range: 49151 - 65535\n(5)All Ports: 0 - 65535\n(6)Custom ")

class switch(object):
    value = None
    def __new__(class_, value):
        class_.value = value
        return True

def case(*args):
    return any((arg == switch.value for arg in args))


while switch(n):



    if case(1):
        print"Your choice is: Standard Ports"
        target= raw_input("Please specify Host or Ip to scan: ")
        targetIP = gethostbyname(target)
        print 'Starting scan on host ', targetIP
        for i in range(0, 1025):
            s = socket(AF_INET, SOCK_STREAM)
            result = s.connect_ex((targetIP, i)


    if case(2):
        print"Your choice is: Middle Range"
        target= raw_input("Please specify Host or Ip to scan: ")
        targetIP = gethostbyname(target)
        print 'Starting scan on host ', targetIP
        for i in range(1025, 5000):
            s = socket(AF_INET, SOCK_STREAM)
            result = s.connect_ex((targetIP, i)
        break

    if case(3):
        print"Your choice is: Higher Range"
        target= raw_input("Please specify Host or Ip to scan: ")
        targetIP = gethostbyname(target)
        print 'Starting scan on host ', targetIP
        for i in range(500, 49151):
            s = socket(AF_INET, SOCK_STREAM)
            result = s.connect_ex((targetIP, i)
        break

    if case(4):
        print"Your choice is: Highest Range"
        target= raw_input("Please specify Host or Ip to scan: ")
        targetIP = gethostbyname(target)
        print 'Starting scan on host ', targetIP
        for i in range(49151, 65535):
            s = socket(AF_INET, SOCK_STREAM)
            result = s.connect_ex((targetIP, i)
        break

    if case(5):
        print"Your choice is: All Ports"
        target= raw_input("Please specify Host or Ip to scan: ")
        targetIP = gethostbyname(target)
        print 'Starting scan on host ', targetIP
        for i in range(0, 65535):
            s = socket(AF_INET, SOCK_STREAM)
            result = s.connect_ex((targetIP, i)
        break

    if case(6):
        print"Your choice is: Custom"
        target= raw_input("Please specify Host or Ip to scan: ")
        targetIP = gethostbyname(target)
        print 'Starting scan on host ', targetIP
        startPort= raw_input("Specify starting Port:")
        endPort= raw_input("Specify end Port:")
        for i in range(startPort, endPort):
            s = socket(AF_INET, SOCK_STREAM)
            result = s.connect_ex((targetIP, i)
        break

3 个答案:

答案 0 :(得分:4)

你试图解决这个问题的方式似乎并不像是pythonic。由于python中不存在switch语句,因此可以使用字典模拟switch类行为,因为函数和类是python中的第一类对象。

def func1():
    # do some operation

def func2():
    # some other operation

def default_func():
    # some default action

options = {
    '1': func1,
    '2': func2,
    'default': default_func
}

value = raw_input('enter a number')

result = options.get(int(value), options.get('default'))()

如果你的功能足够简单,你肯定可以使用lambdas作为值,这肯定会更简洁。

答案 1 :(得分:1)

如果你需要在case-equivalent语句中的代码块之间共享一组局部变量,那么函数的dict可能不是正确的答案。至少,您必须将上下文实体传递给所有函数。或者使用__init__()将它们转换为类方法以初始化它们并将上下文存储在self.whatever

更简单的方法就是使用

if switchvar == value1: 
   ... 
elif switchvar==value2:
   ... 
elif # as many more as you need

else: #default
   ... 

这与案例陈述的不同之处仅在于你不能从一个块的末尾流入下一个块(而对于函数,你可以从其他块中调用)。请注意,在具有case语句的语言中,如果没有大量注释,则将case语句中的一个块的末尾流入下一个块中是不受欢迎的。它通常是一个错误,但偶尔会有用。

请注意,Pythonic if variable in [value1, value2, value3, ...]:相当于同一块顶部的value1,value2,...的多个case标签。

答案 2 :(得分:0)

在 Python 3.10 中将有一种新语法,称为“结构模式匹配”或 match/case。这是它的通用形式:

match subject:
    case <pattern_1>:
        <action_1>
    case <pattern_2>:
        <action_2>
    case <pattern_3>:
        <action_3>
    case _:
        <action_wildcard>

这是一个简单的例子:

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"
        case _:
            return "Something's wrong with the Internet"

链接: