将代码存储在字典

时间:2016-01-19 13:13:27

标签: python function dictionary lambda

我进入Python,虽然编写了我自己的脚本,它允许我检查程序运行时提供的参数。以下是我想要实现的目标的一个例子:

python file.py -v -h anotherfile.py

./file.py -v -h anotherfile.py

在这两种情况下,-v-h参数,打印模块版本和基本帮助文件。我已经有了区分参数和文件的代码,除了我想在这个问题上创建一个通用的模块。

以下用Java编写的代码 -

// Somewhere.
public static HashMap<String, Runnable> args = new HashMap<String, Runnable>();
public void addArgument(String argument, Runnable command) {
    if (argument.length() > 0) {
        if (args.get(argument) == null) {
            args.put(argument, command);
        } else {
            System.err.println("Cannot add argument: " + argument + " to HashMap as the mapping already exists.");
            // Recover.
        }
    }
}

// Somewhere else.
foo.addArgument("-v", () -> {System.out.println("version 1.0");});
foo.args.get("-v").run();

- 将成功运行Lambda表达式(至少是我在研究主题时所读到的内容)。我不知道Lambda Expressions是如何工作的,并且只具备使用它们的基本知识。

这个问题的关键是,如何在Python中实现类似Java示例的东西,在数组中存储任何类型的代码?

但事实是Java示例,如果我在执行int i = 0;的类中定义了addArgument并以某种方式使用i,那么包含addArgument的类知道使用调用它的i。我担心这可能与Python的情况不同......

我希望能够将它们存储在词典或其他类型的基于键的数组中,因此我可以按以下方式存储它们:

# Very rough example on the latter argument, showing what I'm after.
addoption("-v", print("version 1.0"))

编辑:我想要的例子:(不按原样工作)(请忽略;&#39; s)

args = {};

def add(argument, command):
    args[argument] = lambda: command;  # Same problem when removing 'lambda:'

def run():
    for arg in args:
        arg();  # Causing problems.

def prnt():
    print("test");

add("-v", prnt);
run();

4 个答案:

答案 0 :(得分:1)

编辑:要更正最近的代码,迭代字典会产生其键而不是其值,因此您需要:

args = {};

def add(argument, command):
    args[argument] = command;

def run():
    for arg in args:
        args[arg]()     # <<<<<<<<<<

def prnt():
    print("test");

add("-v", prnt);
run();

对于你给出的例子,尽管可能,函数字典并不是用Python做事的自然方式。标准库有一个模块,argparse专门用于处理与所有相关的命令行参数,而不是使用键到字典,你可以解析命令行参数并引用它们存储的常量。

import argparse

def output_version():
    print('Version 1.0!')

parser = argparse.ArgumentParser(description="A program to do something.")
parser.add_argument('-v', help='Output version number.', action='store_true')

args = parser.parse_args()
if args.v:
    output_version()

(实际上,输出版本字符串也由argparse本地处理:请参阅here)。

在给出myfile.txt开关时打印出文本文件-p的内容:

import argparse

def print_file(filename):
    with open(filename) as fi:
        print(fi.read())

parser = argparse.ArgumentParser(description="A program to do something.")
parser.add_argument('-p', help='Print a plain file.', action='store')

args = parser.parse_args()

if args.p:
    print_file(args.p)

使用例如

$ prog.py -p the_filename.txt

答案 1 :(得分:0)

在Python中,您可以简单地将对函数的引用用作数据结构中的值。例如,请考虑以下代码:

def spam():
    print('Ham!')

eggs = [spam, spam, spam]
for x in eggs:
    x()

这将调用函数spam的三个实例。

您所指的lambda expressions只是另一种定义函数的方法,而不必明确地将它们绑定到名称。请考虑以下事项:

eggs = [lambda : print('ham'), lambda : print('spam')]
for x in eggs:
    x()

当你使用参数时,这会变得更加强大:

fn = [lambda x: return x + 3, lambda x: return x * 2]
for f in fn:
    print(f(4))

一旦你有一个函数的引用,你就可以将那个传递给另一个函数。

def foo(x):
    return x + 2

bar = lambda x: return x * 2

def h(g, f, x):
    return g(f(x))

print(h(foo, bar, 37))

但是,在您的方案中,您只需传递lambda : print("version 1.0")

答案 2 :(得分:0)

由于Python函数是第一类对象,因此您可以创建{string: callable}对的字典。

def help():
    print("Usage: xyz")


d = {
    'help': help,
    'version': lambda: print("1.0"), # lambda is also callable
}

在定义之后,用法如下:

my_function = d["help"]  # retrieves function stored under key 'help' in dict
my_function()  # calls function

# or obviously you may drop explainatory variable
d['help']()

它适用于您的自定义解决方案,问题定义如下。

对于创建命令行界面的标准化方法,您可能希望熟悉argparse module

答案 3 :(得分:-1)

Python有一个名为eval()的函数,它接受字符串并尝试将它们作为代码进行评估。

>>> eval("2+3")
5

然后,您可以使用3个引号将代码存储为多行字符串

x = """the quick brown fox
jumps over the
lazy dogs"""

如果你想自己存储这些功能,没有理由不能将它们放在字典中。即使没有lambdas。

def f():
    return 1

def g(x):
    return x + 1

def h(x):
    return 2*x

F = [f,g,h]
G = {"a": f, "b": g, "c": h}

(F[0](), G["a"]())

元组的值为(1,1)。否则我不知道你要的是什么。