我有一个带有几个定义的python文件(以免称为pythonFile.py
),所以我希望所有定义都可以用作使用该文件作为模块的python解释器和linux终端。 E.g:
def funct_1(arg1): #if arg1 is a string
return arg1
def funct_2(arg1, arg2): #if both arg1 and arg2 are integers
return arg1+arg2
def funct_3(arg1, arg2, arg3): #arg1 is str, arg2 is list, and arg3 is dict
if (arg1 is str) and (arg2 is list) and (arg3 is dict):
return 'It is Ok'
else:
return 'It is bad, very bad'
因此,在交互式解释器中使用此脚本可以正常工作:
>>> import pythonFile
>>> func_1('string here')
string here
>>> funct_2(2,4)
6
>>> funct_3(strVar, listVar, dictVar)
It is Ok
要在终端中使用它,我添加了以下代码(导入适当的模块):
if __name__ == "__main__":
print eval(sys.argv[1])(*sys.argv[2:])
因此,eval(sys.argv[1])
告诉我将使用哪个函数,(*sys.argv[2:])
表示我放入的参数和数量。
这适用于funct_1
,它只请求一个字符串:
$ python filePython.py funct_1 'print me'
print me
但不适用于funct_2
和fuct_3
:
$ python filePython.py func_2 6 4`
64
$ python filePython.py func_2 strVar listVar dictVar`
It is bad, very bad
显然,这是因为传递到终端的每个参数都被解析为string
。一种解决方案是在定义中使用eval()
。但是eval()
是"邪恶",所以我更喜欢使用更安全的ast.literal_eval()
。
import sys
from ast import literal_eval as aeval
def funct_1(arg1): #if arg1 is a string
return arg1
def funct_2(arg1, arg2): #if both arg1 and arg2 are integers
return int(arg1)+int(arg2)
def funct_3(arg1, arg2, arg3): #arg1 is str, arg2 is list, and arg3 is dict
if (arg1 is str) and (aveal(arg2) is list) and (aeval(arg3) is dict):
return 'It is Ok'
else:
return 'It is bad, very bad'
if __name__ == "__main__":
print eval(sys.argv[1])(*sys.argv[2:]) # here I still using eval() instead aeval()
请注意,在funct_2
我可以使用int()
或float()
代替任何类型的eval()
来解决问题。
现在,我可以使用终端中的funct_3
:
$ python filePython.py funct_3 strVar listVar dictVar
$ It is Ok
但不是来自python解释器:
>>> import pythonFile
>>> funct_3(strVar, listVar, dictVar)
It is bad, very bad
这是因为aeval()
正在评估list
和dict
而不是string
。所以,我再次更改了我的代码,添加了一个新定义,将dict
和list
转换为str
,稍后由aeval()
进行评估(是的,我知道。是丑陋和愚蠢的,但到目前为止我知道的唯一方法。)
import sys
from ast import literal_eval as aeval
def strEval(var):
return aeval(str(var))
def funct_1(arg1): #if arg1 is a string
return arg1
def funct_2(arg1, arg2): #if both arg1 and arg2 are integers
return int(arg1)+int(arg2)
def funct_3(arg1, arg2, arg3): #arg1 is str, arg2 is list, and arg3 is dict
if (arg1 is str) and (strEval(arg2) is list) and (strEval(arg3) is dict):
return 'It is Ok'
else:
return 'It is bad, very bad'
if __name__ == '__main__':
print eval(sys.argv[1])(*sys.argv[2:])
现在,所有定义都适用于python解释器(作为模块)和linux终端(很棒!)。但我有两个问题:
if __name__ == '__main__':
仍然需要使用邪恶函数eval()
,因为它不适用于ast.literal_eval()
。这是我的两个问题。如果有人能帮助我解决这两个问题,我将非常感激。
答案 0 :(得分:0)
此处无需使用eval()
或ast.literal_eval()
(此处也不存在问题,因为您已经能够从命令行执行代码)。< / p>
Python允许您在命令行上使用表达式:
python -c "import filePython; filePython.funct_3('str', ['listVar'], {'dictVar': 'foo'})"
-c <command>
switch与类固醇eval()
类似,因为它接受完整的陈述,而不仅仅是表达式。试图避免eval()
这里的问题根本不会产生任何差异因为任意代码执行已经发生。