这是一个复杂的问题(至少对我来说),我希望有人可以指点我帮助我开始一本书/网站/博客。有人能告诉我在哪里可以找到信息在python中编写脚本,它会读取一堆逻辑语句并将该逻辑应用于一堆正在读入的数据中吗?我可以用非声明的方式做到这一点,但这意味着任何时候有一个新的逻辑语句,我需要编写新的代码来处理它。如果我可以编写一些可以解释逻辑语句的通用脚本,那么我就不需要继续编写代码来跟上新的逻辑语句了。
我想要做的是我的脚本会读取3个文件。两个长度相等的文件包含两个度量的值。第三个是带有逻辑语句的文件。我希望脚本读入逻辑语句并将这些语句应用于数字,并在满足这些语句时写入消息。
例如,文件1将包含:
1
2
3
4
5
6
文件2将包含:
2
4
6
8
10
3
文件3,将包含:
m1 >=3 && (m1 + m2) >= 11
如果我运行我的脚本,我希望它输出一些说
的内容m1 = 4 and m2 = 8 fulfills condition m1 >= 3 && (m1 + m2) >= 11
m1 = 5 and m2 = 10 fulfills condition m1 >= 3 && (m1 + m2) >= 11
答案 0 :(得分:4)
我会使用eval函数。
>>> m1 = 10
>>> m2 = 30
>>> statement = 'm1 < m2 and m2 == 30'
>>> eval(statement)
True
警告强>
eval()
以python代码的形式执行所有操作,因此如果用户可以输入语句,他可以运行任何内容。在某些网站上可能会非常危险。您总是可以在评估之前解析语句。
def parse(statement, m1, m2):
statement = statement.replace('&&', ' and ')
statement = statement.replace('||', ' or ')
if is_safe(statement):
eval(statement)
def is_safe(to_test):
safe_tags = ('m1', 'm2','>=', '<=', '>', '<', '==', '+', '-', '*', '/', '(', ')', 'and', 'or', '.')
max_number_length = 20
for tag in safe_tags:
to_test = to_test.replace(tag, ' ')
for other in to_test.split(' '):
if other == '':
continue
if other.isdigit() == False or len(other) > max_number_length:
return False
return True
parse('m1 >=3 && (m1 + m2) >= 11', 10, 20)
仅使用允许的标签(白名单)。您可能需要在safe_tags
答案 1 :(得分:2)
如果您信任数据并且可以用Python语法编写逻辑语句,那么您可以使用eval
并为其提供表达式和两个值:
>>> eval('m1 >=3 and (m1 + m2) >= 11', {'m1':4, 'm2':8})
True
>>> eval('m1 >=3 and (m1 + m2) >= 11', {'m1':4, 'm2':-8})
False
使用“如果你信任它”我的意思是它不应该包含像“delete-my-whole-harddisk”函数调用这样的东西。因为eval
会运行它。
不得不为自己尝试......
with open('m1.txt') as f1, open('m2.txt') as f2:
m12 = list(zip(map(int, f1), map(int, f2)))
with open('expressions.txt') as expressions:
for expression in expressions:
for m1, m2 in m12:
if eval(expression):
print('m1 = {} and m2 = {} fulfills condition {}'.
format(m1, m2, expression.strip()))
答案 2 :(得分:2)
按照@AdamSmith的建议使用SQL。问题是condition
仍然容易受到SQL注入攻击,因此与eval相比没有任何优势
import sqlite3
conn = sqlite3.connect(':memory:')
c = conn.cursor()
file1 = [1, 2, 3, 4, 5, 6]
file2 = [2, 4, 6, 8, 10, 3]
c.execute('''CREATE TABLE m (m1, m2)''')
for m1, m2 in zip(file1, file2):
c.execute('''INSERT INTO m VALUES(?, ?)''', (m1, m2))
condition = '''m1 >=3 AND (m1 + m2) >= 11'''
c.execute('''SELECT m1, m2 FROM m WHERE ''' + condition)
for m1, m2 in c.fetchall():
print "m1 = {} and m2 = {} fulfills condition {}".format(m1, m2, condition)