我正在编写一些解析字符串的代码,通常使用简单的关键字。在解析时,代码执行各种操作,例如打印响应、运行函数等,并跟踪是否能够响应
我实际上使用了多个解析器,并在下面的代码中对此进行了说明
有什么更好的方法来构造代码,特别是考虑到可伸缩性和代码紧凑性?例如,假设添加了更多的解析器,它们的操作原理比简单的关键字定位更复杂
中全景:
#!/usr/bin/python
import json
import os
import requests
import subprocess
import sys
def main():
message = "how are you"
#message = "ip address"
#message = "restart"
triggered = [
parse_1(message = message),
parse_2(message = message)
]
if not any(triggered):
report_help()
def parse_1(
message = None
):
def keyphrases_text_response(
message = None,
keyphrases = None,
response = None
):
if any(pattern in message for pattern in keyphrases):
print(response)
return True
else:
return False
triggered = [
keyphrases_text_response(
message = message,
keyphrases = [
"image"
],
response = "http://i.imgur.com/MiqrlTh.jpg"
),
keyphrases_text_response(
message = message,
keyphrases = [
"sup",
"hi"
],
response = "sup home bean"
),
keyphrases_text_response(
message = message,
keyphrases = [
"how are you",
"are you well",
"status"
],
response = "nae bad fam"
),
keyphrases_text_response(
message = message,
keyphrases = [
"help",
"what can you do"
],
response = "I can report my IP address and I can restart my script."
)
]
if any(triggered):
return True
else:
return False
def parse_2(
message = None
):
triggered = []
if any(pattern in message for pattern in\
[
"IP",
"I.P.",
"IP address",
"I.P. address",
"ip address"
]
):
triggered.append(True)
report_IP()
if any(pattern in message for pattern in\
[
"restart"
]
):
triggered.append(True)
restart()
if any(pattern in message for pattern in\
[
"SSH",
"reverse"
]
):
triggered.append(True)
engage_command(
command = "ssh -R 10000:localhost:22 www.sern.ch",
background = True
)
if any(triggered):
return True
else:
return False
def report_IP(
contact = None,
country = True
):
IP = "unknown"
try:
data_IP_website = requests.get("http://ipinfo.io/json")
data_IP = data_IP_website.json()
IP = data_IP["ip"]
country = data_IP["country"]
except:
pass
text = "IP address: " + IP
if country:
text = text + " (" + country + ")"
print(text)
def restart():
print("restart! (and I'm in a crazy loop!)")
import __main__
os.execv(__main__.__file__, sys.argv)
def report_help():
print("I can report my IP address, I can restart my script and I can run commands.")
def engage_command(
command = None,
background = False
):
print("engage command: {command}".format(command = command))
if not background:
process = subprocess.Popen(
[command],
shell = True,
executable = "/bin/bash"
)
process.wait()
output, errors = process.communicate()
return output
else:
subprocess.Popen(
[command],
shell = True,
executable = "/bin/bash"
)
return None
if __name__ == "__main__":
main()
注意:以下代码适用于Python3.5或更高版本。
首先,将解析器的逻辑与通过解析器运行字符串的代码的逻辑分开。让我们从后者的代码开始:
注意:在最新的Python版本中,可以对代码进行注释。我之所以选择在这里这样做,是为了说明这个函数并不关心它得到什么类型的解析器。它需要一个
BaseParser
实例列表(包括从BaseParser
继承的类的实例),然后在message
上调用每个实例的parse_sting
方法。这个函数不关心parse_message
做什么。接下来,您要为解析器对象定义一个API,以便
run_parsers
可以使用它们而不知道它们是如何工作的如您所见
BaseParser
几乎没有逻辑,它只是说从我继承的人应该定义parse_message
。而且,继承者得到一个triggered
属性。现在,让我们看看一个这样的继承者的代码
只要继承者遵循BaseInheriter设置的“规则”(即实现一个方法并拥有一个名为
triggered
的属性),run_parsers
就会愉快地运行它们。注意:
ImageParser
将triggered
设置为True,这就是如何确定哪些解析器采取了某些操作。最后,我们将
main
函数转换为上面的代码:重要提示:确保阅读并使用pep8 guidelines。面向对象的设计使应用程序的流程复杂化,并且您不希望通过提出自己的代码样式或约定而使事情进一步复杂化
如果您希望在增加解析模式的复杂性和数量的同时生成更多python代码,那么至少应该检查正则表达式。一开始它们相当吓人,但是一旦你越过了一点障碍,如果你定期创建代码来匹配模式,它们会极大地提高你的生产力。python标准库中的re module非常易于使用。下面是一个示例代码,它将匹配解析2中的ip地址请求
从您的格式看来,您可能有丰富的编程经验,但可能是python新手。如前所述,您应该查看PEP-8 style guide。Python还提供了一些非常棒的特性,这些特性使您可以更轻松地完成您要做的事情。如果您想对许多模式使用regex,并且如果任何模式与当前程序的方式相似,则返回True,您可能需要执行以下操作:
如果您想找个地方快速练习regex语法来掌握它的窍门,try here
相关问题 更多 >
编程相关推荐